Stop propagation of keydown events on modal level.

--- src/shared/ModalDialog.js
+++ src/shared/ModalDialog.js
@@ -25,6 +25,7 @@
     // TODO: don't think that this is good enough. Right the modal is closed by any unhandled click.
     // Need to be discussed.
     el.on('click', this._closeModal)
+    el.on('keydown', this._onKeydown)

     if (this.props.width) {
       el.addClass('sm-width-'+this.props.width)
@@ -42,6 +43,10 @@
     return el
   }

+  _onKeydown(e) {
+    e.stopPropagation()
+  }
+
   _closeModal(e) {
     e.preventDefault()
     e.stopPropagation()

<|original_code|>
import { Component } from 'substance'

/**
  ModalDialog component

  @class
  @component

  @prop {String} width 'small', 'medium', 'large' and 'full'

  @example

  ```js
  var form = $$(ModalDialog, {
    width: 'medium',
    textAlign: 'center'
  });
  ```
*/
export default class ModalDialog extends Component {

  render($$) {
    let el = $$('div').addClass('sc-modal-dialog')

    // TODO: don't think that this is good enough. Right the modal is closed by any unhandled click.
    // Need to be discussed.
    el.on('click', this._closeModal)

    if (this.props.width) {
      el.addClass('sm-width-'+this.props.width)
    }

    if (this.props.transparent) {
      el.addClass('sm-transparent-bg')
    }

    el.append(
      $$('div').addClass('se-body').append(
        this.props.children
      )
    )
    return el
  }

  _closeModal(e) {
    e.preventDefault()
    e.stopPropagation()
    let closeSurfaceClick = e.target.classList.contains('sc-modal-dialog')
    if (closeSurfaceClick) {
      this.send('closeModal')
    }
  }
}

<|edits_diff|>
--- src/shared/ModalDialog.js
+++ src/shared/ModalDialog.js
@@ -25,6 +25,7 @@
     // TODO: don't think that this is good enough. Right the modal is closed by any unhandled click.
     // Need to be discussed.
     el.on('click', this._closeModal)
+    el.on('keydown', this._onKeydown)

     if (this.props.width) {
       el.addClass('sm-width-'+this.props.width)
<|current_version|>
import { Component } from 'substance'

/**
  ModalDialog component

  @class
  @component

  @prop {String} width 'small', 'medium', 'large' and 'full'

  @example

  ```js
  var form = $$(ModalDialog, {
    width: 'medium',
    textAlign: 'center'
  });
  ```
*/
export default class ModalDialog extends Component {

  render($$) {
    let el = $$('div').addClass('sc-modal-dialog')

    // TODO: don't think that this is good enough. Right the modal is closed by any unhandled click.
    // Need to be discussed.
    el.on('click', this._closeModal)
    el.on('keydown', this._onKeydown)

    if (this.props.width) {
      el.addClass('sm-width-'+this.props.width)
    }

    if (this.props.transparent) {
      el.addClass('sm-transparent-bg')
    }

    el.append(
      $$('div').addClass('se-body').append(
        this.props.children
      )
    )
    return el
  }

  _closeModal(e) {
    e.preventDefault()
    e.stopPropagation()
    let closeSurfaceClick = e.target.classList.contains('sc-modal-dialog')
    if (closeSurfaceClick) {
      this.send('closeModal')
    }
  }
}

<|next_version|>
import { Component } from 'substance'

/**
  ModalDialog component

  @class
  @component

  @prop {String} width 'small', 'medium', 'large' and 'full'

  @example

  ```js
  var form = $$(ModalDialog, {
    width: 'medium',
    textAlign: 'center'
  });
  ```
*/
export default class ModalDialog extends Component {

  render($$) {
    let el = $$('div').addClass('sc-modal-dialog')

    // TODO: don't think that this is good enough. Right the modal is closed by any unhandled click.
    // Need to be discussed.
    el.on('click', this._closeModal)
    el.on('keydown', this._onKeydown)

    if (this.props.width) {
      el.addClass('sm-width-'+this.props.width)
    }

    if (this.props.transparent) {
      el.addClass('sm-transparent-bg')
    }

    el.append(
      $$('div').addClass('se-body').append(
        this.props.children
      )
    )
    return el
  }

  _onKeydown(e) {
    e.stopPropagation()
  }

  _closeModal(e) {
    e.preventDefault()
    e.stopPropagation()
    let closeSurfaceClick = e.target.classList.contains('sc-modal-dialog')
    if (closeSurfaceClick) {
      this.send('closeModal')
    }
  }
}


Add assertion about undefined entitlements property

--- test.js
+++ test.js
@@ -11,6 +11,9 @@
       assert.equal(data.metadata['CFBundleName'], 'Test App');
       assert.equal(data.metadata['CFBundleShortVersionString'], '1.0.0');
       assert.equal(data.metadata['CFBundleVersion'], '1337');
+
+      // Property is only set on OS X
+      assert.equal(data.entitlements, void 0);

       done();
     });
@@ -26,6 +29,9 @@
       assert.equal(data.metadata['CFBundleShortVersionString'], '1.0.0');
       assert.equal(data.metadata['CFBundleVersion'], '1337');

+      // Property is only set on OS X
+      assert.equal(data.entitlements, void 0);
+
       done();
     });
   });

<|original_code|>
'use strict';

var assert = require('assert');
var ipaMetadataParser = require('./');

describe('should parse .ipa file', function(){
  it('should contain the correct data', function(done) {
    ipaMetadataParser('tests/fixtures/testApp.ipa', function(err, data) {
      assert.equal(data.metadata['CFBundleDisplayName'], 'Test App');
      assert.equal(data.metadata['CFBundleIdentifier'], 'io.mts.testapp');
      assert.equal(data.metadata['CFBundleName'], 'Test App');
      assert.equal(data.metadata['CFBundleShortVersionString'], '1.0.0');
      assert.equal(data.metadata['CFBundleVersion'], '1337');

      done();
    });
  });
});

describe('should parse .ipa files with binary .plist files', function(){
  it('should contain the correct data', function(done) {
    ipaMetadataParser('tests/fixtures/testApp-binaryPlist.ipa', function(err, data) {
      assert.equal(data.metadata['CFBundleDisplayName'], 'Test App');
      assert.equal(data.metadata['CFBundleIdentifier'], 'io.mts.testapp');
      assert.equal(data.metadata['CFBundleName'], 'Test App');
      assert.equal(data.metadata['CFBundleShortVersionString'], '1.0.0');
      assert.equal(data.metadata['CFBundleVersion'], '1337');

      done();
    });
  });
});

<|edits_diff|>
--- test.js
+++ test.js
@@ -11,6 +11,9 @@
       assert.equal(data.metadata['CFBundleName'], 'Test App');
       assert.equal(data.metadata['CFBundleShortVersionString'], '1.0.0');
       assert.equal(data.metadata['CFBundleVersion'], '1337');
+
+      // Property is only set on OS X
+      assert.equal(data.entitlements, void 0);

       done();
     });
<|current_version|>
'use strict';

var assert = require('assert');
var ipaMetadataParser = require('./');

describe('should parse .ipa file', function(){
  it('should contain the correct data', function(done) {
    ipaMetadataParser('tests/fixtures/testApp.ipa', function(err, data) {
      assert.equal(data.metadata['CFBundleDisplayName'], 'Test App');
      assert.equal(data.metadata['CFBundleIdentifier'], 'io.mts.testapp');
      assert.equal(data.metadata['CFBundleName'], 'Test App');
      assert.equal(data.metadata['CFBundleShortVersionString'], '1.0.0');
      assert.equal(data.metadata['CFBundleVersion'], '1337');

      // Property is only set on OS X
      assert.equal(data.entitlements, void 0);

      done();
    });
  });
});

describe('should parse .ipa files with binary .plist files', function(){
  it('should contain the correct data', function(done) {
    ipaMetadataParser('tests/fixtures/testApp-binaryPlist.ipa', function(err, data) {
      assert.equal(data.metadata['CFBundleDisplayName'], 'Test App');
      assert.equal(data.metadata['CFBundleIdentifier'], 'io.mts.testapp');
      assert.equal(data.metadata['CFBundleName'], 'Test App');
      assert.equal(data.metadata['CFBundleShortVersionString'], '1.0.0');
      assert.equal(data.metadata['CFBundleVersion'], '1337');

      done();
    });
  });
});

<|next_version|>
'use strict';

var assert = require('assert');
var ipaMetadataParser = require('./');

describe('should parse .ipa file', function(){
  it('should contain the correct data', function(done) {
    ipaMetadataParser('tests/fixtures/testApp.ipa', function(err, data) {
      assert.equal(data.metadata['CFBundleDisplayName'], 'Test App');
      assert.equal(data.metadata['CFBundleIdentifier'], 'io.mts.testapp');
      assert.equal(data.metadata['CFBundleName'], 'Test App');
      assert.equal(data.metadata['CFBundleShortVersionString'], '1.0.0');
      assert.equal(data.metadata['CFBundleVersion'], '1337');

      // Property is only set on OS X
      assert.equal(data.entitlements, void 0);

      done();
    });
  });
});

describe('should parse .ipa files with binary .plist files', function(){
  it('should contain the correct data', function(done) {
    ipaMetadataParser('tests/fixtures/testApp-binaryPlist.ipa', function(err, data) {
      assert.equal(data.metadata['CFBundleDisplayName'], 'Test App');
      assert.equal(data.metadata['CFBundleIdentifier'], 'io.mts.testapp');
      assert.equal(data.metadata['CFBundleName'], 'Test App');
      assert.equal(data.metadata['CFBundleShortVersionString'], '1.0.0');
      assert.equal(data.metadata['CFBundleVersion'], '1337');

      // Property is only set on OS X
      assert.equal(data.entitlements, void 0);

      done();
    });
  });
});


Return cancelers from Aff actions

Return cancelers from Aff actions

--- src/Database/PostgreSQL.js
+++ src/Database/PostgreSQL.js
@@ -1,10 +1,12 @@
 'use strict';

+var Control_Monad_Aff = require('../Control.Monad.Aff');
 var pg = require('pg');

 exports.newPool = function(config) {
     return function(onSuccess, onError) {
         onSuccess(new pg.Pool(config));
+        return Control_Monad_Aff.nonCanceler;
     };
 };

@@ -24,6 +26,7 @@
                     onError(e);
                 });
             });
+            return Control_Monad_Aff.nonCanceler;
         };
     };
 };
@@ -43,6 +46,7 @@
                     }
                     onSuccess(result.rows);
                 });
+                return Control_Monad_Aff.nonCanceler;
             };
         };
     };

<|original_code|>
'use strict';

var pg = require('pg');

exports.newPool = function(config) {
    return function(onSuccess, onError) {
        onSuccess(new pg.Pool(config));
    };
};

exports.withConnection = function(pool) {
    return function(body) {
        return function(onSuccess, onError) {
            pool.connect(function(err, client, done) {
                if (err !== null) {
                    onError(err);
                    return;
                }
                body(client)(function(r) {
                    done();
                    onSuccess(r);
                }, function(e) {
                    done();
                    onError(e);
                });
            });
        };
    };
};

exports._query = function(client) {
    return function(sql) {
        return function(values) {
            return function(onSuccess, onError) {
                client.query({
                    text: sql,
                    values: values,
                    rowMode: 'array',
                }, function(err, result) {
                    if (err !== null) {
                        onError(err);
                        return;
                    }
                    onSuccess(result.rows);
                });
            };
        };
    };
};

exports.unsafeIsBuffer = function(x) {
    return x instanceof Buffer;
};

<|edits_diff|>
--- src/Database/PostgreSQL.js
+++ src/Database/PostgreSQL.js
@@ -1,10 +1,12 @@
 'use strict';

+var Control_Monad_Aff = require('../Control.Monad.Aff');
 var pg = require('pg');

 exports.newPool = function(config) {
     return function(onSuccess, onError) {
         onSuccess(new pg.Pool(config));
+        return Control_Monad_Aff.nonCanceler;
     };
 };

@@ -24,6 +26,7 @@
                     onError(e);
                 });
             });
+            return Control_Monad_Aff.nonCanceler;
         };
     };
 };
<|current_version|>
'use strict';

var Control_Monad_Aff = require('../Control.Monad.Aff');
var pg = require('pg');

exports.newPool = function(config) {
    return function(onSuccess, onError) {
        onSuccess(new pg.Pool(config));
        return Control_Monad_Aff.nonCanceler;
    };
};

exports.withConnection = function(pool) {
    return function(body) {
        return function(onSuccess, onError) {
            pool.connect(function(err, client, done) {
                if (err !== null) {
                    onError(err);
                    return;
                }
                body(client)(function(r) {
                    done();
                    onSuccess(r);
                }, function(e) {
                    done();
                    onError(e);
                });
            });
            return Control_Monad_Aff.nonCanceler;
        };
    };
};

exports._query = function(client) {
    return function(sql) {
        return function(values) {
            return function(onSuccess, onError) {
                client.query({
                    text: sql,
                    values: values,
                    rowMode: 'array',
                }, function(err, result) {
                    if (err !== null) {
                        onError(err);
                        return;
                    }
                    onSuccess(result.rows);
                });
            };
        };
    };
};

exports.unsafeIsBuffer = function(x) {
    return x instanceof Buffer;
};

<|next_version|>
'use strict';

var Control_Monad_Aff = require('../Control.Monad.Aff');
var pg = require('pg');

exports.newPool = function(config) {
    return function(onSuccess, onError) {
        onSuccess(new pg.Pool(config));
        return Control_Monad_Aff.nonCanceler;
    };
};

exports.withConnection = function(pool) {
    return function(body) {
        return function(onSuccess, onError) {
            pool.connect(function(err, client, done) {
                if (err !== null) {
                    onError(err);
                    return;
                }
                body(client)(function(r) {
                    done();
                    onSuccess(r);
                }, function(e) {
                    done();
                    onError(e);
                });
            });
            return Control_Monad_Aff.nonCanceler;
        };
    };
};

exports._query = function(client) {
    return function(sql) {
        return function(values) {
            return function(onSuccess, onError) {
                client.query({
                    text: sql,
                    values: values,
                    rowMode: 'array',
                }, function(err, result) {
                    if (err !== null) {
                        onError(err);
                        return;
                    }
                    onSuccess(result.rows);
                });
                return Control_Monad_Aff.nonCanceler;
            };
        };
    };
};

exports.unsafeIsBuffer = function(x) {
    return x instanceof Buffer;
};


Add app name as papertrail hostname.

Add app name as papertrail hostname.

--- logger.js
+++ logger.js
@@ -1,11 +1,13 @@
 const winston = require('winston');
 require('winston-papertrail').Papertrail;
+const {name} = require('./package.json');
 const {PAPERTRAIL_HOST, PAPERTRAIL_PORT} = process.env;

 if (PAPERTRAIL_HOST && PAPERTRAIL_PORT) {
   const winstonPapertrail = new winston.transports.Papertrail({
     host: PAPERTRAIL_HOST,
     port: PAPERTRAIL_PORT,
+    hostname: name,
     handleExceptions: true,
     json: true
   });

<|original_code|>
const winston = require('winston');
require('winston-papertrail').Papertrail;
const {PAPERTRAIL_HOST, PAPERTRAIL_PORT} = process.env;

if (PAPERTRAIL_HOST && PAPERTRAIL_PORT) {
  const winstonPapertrail = new winston.transports.Papertrail({
    host: PAPERTRAIL_HOST,
    port: PAPERTRAIL_PORT,
    handleExceptions: true,
    json: true
  });

  const logger = new winston.Logger({
    transports: [winstonPapertrail],
    exitOnError: false
  });

  module.exports = logger;
} else {
  module.exports = console;
}

<|edits_diff|>
--- logger.js
+++ logger.js
@@ -1,5 +1,6 @@
 const winston = require('winston');
 require('winston-papertrail').Papertrail;
+const {name} = require('./package.json');
 const {PAPERTRAIL_HOST, PAPERTRAIL_PORT} = process.env;

 if (PAPERTRAIL_HOST && PAPERTRAIL_PORT) {
<|current_version|>
const winston = require('winston');
require('winston-papertrail').Papertrail;
const {name} = require('./package.json');
const {PAPERTRAIL_HOST, PAPERTRAIL_PORT} = process.env;

if (PAPERTRAIL_HOST && PAPERTRAIL_PORT) {
  const winstonPapertrail = new winston.transports.Papertrail({
    host: PAPERTRAIL_HOST,
    port: PAPERTRAIL_PORT,
    handleExceptions: true,
    json: true
  });

  const logger = new winston.Logger({
    transports: [winstonPapertrail],
    exitOnError: false
  });

  module.exports = logger;
} else {
  module.exports = console;
}

<|next_version|>
const winston = require('winston');
require('winston-papertrail').Papertrail;
const {name} = require('./package.json');
const {PAPERTRAIL_HOST, PAPERTRAIL_PORT} = process.env;

if (PAPERTRAIL_HOST && PAPERTRAIL_PORT) {
  const winstonPapertrail = new winston.transports.Papertrail({
    host: PAPERTRAIL_HOST,
    port: PAPERTRAIL_PORT,
    hostname: name,
    handleExceptions: true,
    json: true
  });

  const logger = new winston.Logger({
    transports: [winstonPapertrail],
    exitOnError: false
  });

  module.exports = logger;
} else {
  module.exports = console;
}


Send the search object back

Send the search object back

--- test/index.js
+++ test/index.js
@@ -6,7 +6,9 @@
 });

 app.on("request", function (lien) {
+    console.log(lien.req.url);
     lien.end({
         foo: "bar"
+      , search: lien.search
     });
 });

<|original_code|>
var Lien = require("../lib/index");

var app = new Lien({
    host: "localhost"
  , port: 9000
});

app.on("request", function (lien) {
    lien.end({
        foo: "bar"
    });
});

<|edits_diff|>
--- test/index.js
+++ test/index.js
@@ -6,6 +6,7 @@
 });

 app.on("request", function (lien) {
+    console.log(lien.req.url);
     lien.end({
         foo: "bar"
     });
<|current_version|>
var Lien = require("../lib/index");

var app = new Lien({
    host: "localhost"
  , port: 9000
});

app.on("request", function (lien) {
    console.log(lien.req.url);
    lien.end({
        foo: "bar"
    });
});

<|next_version|>
var Lien = require("../lib/index");

var app = new Lien({
    host: "localhost"
  , port: 9000
});

app.on("request", function (lien) {
    console.log(lien.req.url);
    lien.end({
        foo: "bar"
      , search: lien.search
    });
});


Add API version to S3

[ADD] Add API version to S3

--- src/server/db/s3.js
+++ src/server/db/s3.js
@@ -4,12 +4,14 @@
 const AWS_S3_UPLOAD_BUCKET = process.env.AWS_S3_UPLOAD_BUCKET;

 const s3 = new S3({
+	apiVersion: '2006-03-01',
 	accessKeyId: process.env.AWS_S3_USER_ACCESS_KEY_ID,
 	secretAccessKey: process.env.AWS_S3_USER_SECRET_ACCESS_KEY,
 	region: process.env.AWS_S3_REGION
 });

 const s3Admin = new S3({
+	apiVersion: '2006-03-01',
 	accessKeyId: process.env.AWS_S3_ADMIN_ACCESS_KEY_ID,
 	secretAccessKey: process.env.AWS_S3_ADMIN_SECRET_ACCESS_KEY,
 	region: process.env.AWS_S3_REGION

<|original_code|>
import S3 from 'aws-sdk/clients/s3';

const AWS_S3_UPLOAD_BUCKET = process.env.AWS_S3_UPLOAD_BUCKET;

const s3 = new S3({
	accessKeyId: process.env.AWS_S3_USER_ACCESS_KEY_ID,
	secretAccessKey: process.env.AWS_S3_USER_SECRET_ACCESS_KEY,
	region: process.env.AWS_S3_REGION
});

const s3Admin = new S3({
	accessKeyId: process.env.AWS_S3_ADMIN_ACCESS_KEY_ID,
	secretAccessKey: process.env.AWS_S3_ADMIN_SECRET_ACCESS_KEY,
	region: process.env.AWS_S3_REGION
});

export {
	s3,
	s3Admin,
	AWS_S3_UPLOAD_BUCKET
}

<|edits_diff|>
--- src/server/db/s3.js
+++ src/server/db/s3.js
@@ -4,6 +4,7 @@
 const AWS_S3_UPLOAD_BUCKET = process.env.AWS_S3_UPLOAD_BUCKET;

 const s3 = new S3({
+	apiVersion: '2006-03-01',
 	accessKeyId: process.env.AWS_S3_USER_ACCESS_KEY_ID,
 	secretAccessKey: process.env.AWS_S3_USER_SECRET_ACCESS_KEY,
 	region: process.env.AWS_S3_REGION
<|current_version|>
import S3 from 'aws-sdk/clients/s3';

const AWS_S3_UPLOAD_BUCKET = process.env.AWS_S3_UPLOAD_BUCKET;

const s3 = new S3({
	apiVersion: '2006-03-01',
	accessKeyId: process.env.AWS_S3_USER_ACCESS_KEY_ID,
	secretAccessKey: process.env.AWS_S3_USER_SECRET_ACCESS_KEY,
	region: process.env.AWS_S3_REGION
});

const s3Admin = new S3({
	accessKeyId: process.env.AWS_S3_ADMIN_ACCESS_KEY_ID,
	secretAccessKey: process.env.AWS_S3_ADMIN_SECRET_ACCESS_KEY,
	region: process.env.AWS_S3_REGION
});

export {
	s3,
	s3Admin,
	AWS_S3_UPLOAD_BUCKET
}

<|next_version|>
import S3 from 'aws-sdk/clients/s3';

const AWS_S3_UPLOAD_BUCKET = process.env.AWS_S3_UPLOAD_BUCKET;

const s3 = new S3({
	apiVersion: '2006-03-01',
	accessKeyId: process.env.AWS_S3_USER_ACCESS_KEY_ID,
	secretAccessKey: process.env.AWS_S3_USER_SECRET_ACCESS_KEY,
	region: process.env.AWS_S3_REGION
});

const s3Admin = new S3({
	apiVersion: '2006-03-01',
	accessKeyId: process.env.AWS_S3_ADMIN_ACCESS_KEY_ID,
	secretAccessKey: process.env.AWS_S3_ADMIN_SECRET_ACCESS_KEY,
	region: process.env.AWS_S3_REGION
});

export {
	s3,
	s3Admin,
	AWS_S3_UPLOAD_BUCKET
}


Add build date to globals

Add build date to globals

--- config.js
+++ config.js
@@ -2,6 +2,7 @@

 // Dependencies
 const cssnext = require('cssnext')
+const moment = require('moment')
 const path = require('path')

 // Aliases
@@ -43,6 +44,7 @@
   },

   globals: {
+    buildDate: moment(),
     env: env,
     site: {
       title: 'Steffen Bruchmann’s Website'

<|original_code|>
'use strict';

// Dependencies
const cssnext = require('cssnext')
const path = require('path')

// Aliases
let basedir = __dirname
let env = process.env.NODE_ENV

module.exports = {
  env: env,

  paths: {
    destination: path.join(basedir, 'dist'),
    source: path.join(basedir, 'src'),
    templates: path.join(basedir, 'templates')
  },

  processors: {
    defaults: {
      '*.md': {
        kind: 'page',
        template: 'page'
      },
      'posts/**/*.md': {
        kind: 'post',
        permalink: false,
        template: 'post'
      }
    },
    extractPathData: {
      'posts/**/*.md': 'posts/{category}/{date}--{slug}.md'
    },
    rewritePath: {
      'posts/**/*.md': function(file) {
        return ['blog', file.category, file.slug + '.html'].join('/')
      }
    },
    postcss: [
      cssnext()
    ]
  },

  globals: {
    env: env,
    site: {
      title: 'Steffen Bruchmann’s Website'
    }
  }
}

<|edits_diff|>
--- config.js
+++ config.js
@@ -2,6 +2,7 @@

 // Dependencies
 const cssnext = require('cssnext')
+const moment = require('moment')
 const path = require('path')

 // Aliases
<|current_version|>
'use strict';

// Dependencies
const cssnext = require('cssnext')
const moment = require('moment')
const path = require('path')

// Aliases
let basedir = __dirname
let env = process.env.NODE_ENV

module.exports = {
  env: env,

  paths: {
    destination: path.join(basedir, 'dist'),
    source: path.join(basedir, 'src'),
    templates: path.join(basedir, 'templates')
  },

  processors: {
    defaults: {
      '*.md': {
        kind: 'page',
        template: 'page'
      },
      'posts/**/*.md': {
        kind: 'post',
        permalink: false,
        template: 'post'
      }
    },
    extractPathData: {
      'posts/**/*.md': 'posts/{category}/{date}--{slug}.md'
    },
    rewritePath: {
      'posts/**/*.md': function(file) {
        return ['blog', file.category, file.slug + '.html'].join('/')
      }
    },
    postcss: [
      cssnext()
    ]
  },

  globals: {
    env: env,
    site: {
      title: 'Steffen Bruchmann’s Website'
    }
  }
}

<|next_version|>
'use strict';

// Dependencies
const cssnext = require('cssnext')
const moment = require('moment')
const path = require('path')

// Aliases
let basedir = __dirname
let env = process.env.NODE_ENV

module.exports = {
  env: env,

  paths: {
    destination: path.join(basedir, 'dist'),
    source: path.join(basedir, 'src'),
    templates: path.join(basedir, 'templates')
  },

  processors: {
    defaults: {
      '*.md': {
        kind: 'page',
        template: 'page'
      },
      'posts/**/*.md': {
        kind: 'post',
        permalink: false,
        template: 'post'
      }
    },
    extractPathData: {
      'posts/**/*.md': 'posts/{category}/{date}--{slug}.md'
    },
    rewritePath: {
      'posts/**/*.md': function(file) {
        return ['blog', file.category, file.slug + '.html'].join('/')
      }
    },
    postcss: [
      cssnext()
    ]
  },

  globals: {
    buildDate: moment(),
    env: env,
    site: {
      title: 'Steffen Bruchmann’s Website'
    }
  }
}


Manipulation: Check state lost if the name is set for Android 4.0-4.3

Refs gh-1820
Closes gh-1841

--- src/manipulation/support.js
+++ src/manipulation/support.js
@@ -7,10 +7,13 @@
 		div = fragment.appendChild( document.createElement( "div" ) ),
 		input = document.createElement( "input" );

+	// Support: Android 4.0-4.3
+	// Check state lost if the name is set (#11217)
 	// Support: Windows Web Apps (WWA)
 	// `name` and `type` must use .setAttribute for WWA (#14901)
 	input.setAttribute( "type", "radio" );
 	input.setAttribute( "checked", "checked" );
+	input.setAttribute( "name", "t" );

 	div.appendChild( input );

<|original_code|>
define([
	"../var/support"
], function( support ) {

(function() {
	var fragment = document.createDocumentFragment(),
		div = fragment.appendChild( document.createElement( "div" ) ),
		input = document.createElement( "input" );

	// Support: Windows Web Apps (WWA)
	// `name` and `type` must use .setAttribute for WWA (#14901)
	input.setAttribute( "type", "radio" );
	input.setAttribute( "checked", "checked" );

	div.appendChild( input );

	// Support: Android<4.2
	// Older WebKit doesn't clone checked state correctly in fragments
	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;

	// Support: IE<=11+
	// Make sure textarea (and checkbox) defaultValue is properly cloned
	div.innerHTML = "<textarea>x</textarea>";
	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
})();

return support;

});

<|edits_diff|>
--- src/manipulation/support.js
+++ src/manipulation/support.js
@@ -7,6 +7,8 @@
 		div = fragment.appendChild( document.createElement( "div" ) ),
 		input = document.createElement( "input" );

+	// Support: Android 4.0-4.3
+	// Check state lost if the name is set (#11217)
 	// Support: Windows Web Apps (WWA)
 	// `name` and `type` must use .setAttribute for WWA (#14901)
 	input.setAttribute( "type", "radio" );
<|current_version|>
define([
	"../var/support"
], function( support ) {

(function() {
	var fragment = document.createDocumentFragment(),
		div = fragment.appendChild( document.createElement( "div" ) ),
		input = document.createElement( "input" );

	// Support: Android 4.0-4.3
	// Check state lost if the name is set (#11217)
	// Support: Windows Web Apps (WWA)
	// `name` and `type` must use .setAttribute for WWA (#14901)
	input.setAttribute( "type", "radio" );
	input.setAttribute( "checked", "checked" );

	div.appendChild( input );

	// Support: Android<4.2
	// Older WebKit doesn't clone checked state correctly in fragments
	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;

	// Support: IE<=11+
	// Make sure textarea (and checkbox) defaultValue is properly cloned
	div.innerHTML = "<textarea>x</textarea>";
	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
})();

return support;

});

<|next_version|>
define([
	"../var/support"
], function( support ) {

(function() {
	var fragment = document.createDocumentFragment(),
		div = fragment.appendChild( document.createElement( "div" ) ),
		input = document.createElement( "input" );

	// Support: Android 4.0-4.3
	// Check state lost if the name is set (#11217)
	// Support: Windows Web Apps (WWA)
	// `name` and `type` must use .setAttribute for WWA (#14901)
	input.setAttribute( "type", "radio" );
	input.setAttribute( "checked", "checked" );
	input.setAttribute( "name", "t" );

	div.appendChild( input );

	// Support: Android<4.2
	// Older WebKit doesn't clone checked state correctly in fragments
	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;

	// Support: IE<=11+
	// Make sure textarea (and checkbox) defaultValue is properly cloned
	div.innerHTML = "<textarea>x</textarea>";
	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
})();

return support;

});


Add auth0 management service to user controller

--- controllers/users.js
+++ controllers/users.js
@@ -1,8 +1,13 @@
 const users = require('collections-online/lib/controllers/users');
 const kbhStatsApi = require('../services/kbh-billeder-stats-api');
+const auth0 = require('collections-online/lib/services/auth0');
+
+const Service = auth0.Service

 users.renderProfile = async (req, res) => {
   const { user } = req;
+
+  console.log(await Service)

   let points = kbhStatsApi.userPoints(user.id);
   let stats = kbhStatsApi.userStats(user.id);

<|original_code|>
const users = require('collections-online/lib/controllers/users');
const kbhStatsApi = require('../services/kbh-billeder-stats-api');

users.renderProfile = async (req, res) => {
  const { user } = req;

  let points = kbhStatsApi.userPoints(user.id);
  let stats = kbhStatsApi.userStats(user.id);

  try {
    [points, stats] = [await points, await stats]
  } catch(err) {
    console.log(err)
  }

  res.render('profile', {points , stats, user})
}

module.exports = users;

<|edits_diff|>
--- controllers/users.js
+++ controllers/users.js
@@ -1,5 +1,8 @@
 const users = require('collections-online/lib/controllers/users');
 const kbhStatsApi = require('../services/kbh-billeder-stats-api');
+const auth0 = require('collections-online/lib/services/auth0');
+
+const Service = auth0.Service

 users.renderProfile = async (req, res) => {
   const { user } = req;
<|current_version|>
const users = require('collections-online/lib/controllers/users');
const kbhStatsApi = require('../services/kbh-billeder-stats-api');
const auth0 = require('collections-online/lib/services/auth0');

const Service = auth0.Service

users.renderProfile = async (req, res) => {
  const { user } = req;

  let points = kbhStatsApi.userPoints(user.id);
  let stats = kbhStatsApi.userStats(user.id);

  try {
    [points, stats] = [await points, await stats]
  } catch(err) {
    console.log(err)
  }

  res.render('profile', {points , stats, user})
}

module.exports = users;

<|next_version|>
const users = require('collections-online/lib/controllers/users');
const kbhStatsApi = require('../services/kbh-billeder-stats-api');
const auth0 = require('collections-online/lib/services/auth0');

const Service = auth0.Service

users.renderProfile = async (req, res) => {
  const { user } = req;

  console.log(await Service)

  let points = kbhStatsApi.userPoints(user.id);
  let stats = kbhStatsApi.userStats(user.id);

  try {
    [points, stats] = [await points, await stats]
  } catch(err) {
    console.log(err)
  }

  res.render('profile', {points , stats, user})
}

module.exports = users;


Remove uncaught exception handlers from dependencies

--- deps/nopus/index.js
+++ deps/nopus/index.js
@@ -1,5 +1,11 @@
+var ex = "uncaughtException";
+var pl = process.listeners(ex);
+
 var opus = require("./opus-js/opus");
 var resampler = require("./opus-js/resampler");
+
+process.removeAllListeners(ex);
+for (var i = 0; i < pl.length; i++) process.on(ex, pl[i]);

 module.exports.Opus = opus.Opus;
 module.exports.OpusApplication = opus.OpusApplication;

<|original_code|>
var opus = require("./opus-js/opus");
var resampler = require("./opus-js/resampler");

module.exports.Opus = opus.Opus;
module.exports.OpusApplication = opus.OpusApplication;
module.exports.OpusEncoder = opus.OpusEncoder;
module.exports.OpusDecoder = opus.OpusDecoder;
module.exports.Resampler = resampler.SpeexResampler;

<|edits_diff|>
--- deps/nopus/index.js
+++ deps/nopus/index.js
@@ -1,3 +1,6 @@
+var ex = "uncaughtException";
+var pl = process.listeners(ex);
+
 var opus = require("./opus-js/opus");
 var resampler = require("./opus-js/resampler");

<|current_version|>
var ex = "uncaughtException";
var pl = process.listeners(ex);

var opus = require("./opus-js/opus");
var resampler = require("./opus-js/resampler");

module.exports.Opus = opus.Opus;
module.exports.OpusApplication = opus.OpusApplication;
module.exports.OpusEncoder = opus.OpusEncoder;
module.exports.OpusDecoder = opus.OpusDecoder;
module.exports.Resampler = resampler.SpeexResampler;

<|next_version|>
var ex = "uncaughtException";
var pl = process.listeners(ex);

var opus = require("./opus-js/opus");
var resampler = require("./opus-js/resampler");

process.removeAllListeners(ex);
for (var i = 0; i < pl.length; i++) process.on(ex, pl[i]);

module.exports.Opus = opus.Opus;
module.exports.OpusApplication = opus.OpusApplication;
module.exports.OpusEncoder = opus.OpusEncoder;
module.exports.OpusDecoder = opus.OpusDecoder;
module.exports.Resampler = resampler.SpeexResampler;


Hide notification before redirecting to login

Closes #514

--- src/sideEffect/saga/auth.js
+++ src/sideEffect/saga/auth.js
@@ -1,10 +1,12 @@
 import { put, takeEvery } from 'redux-saga/effects';
 import { push } from 'react-router-redux';
 import { FETCH_ERROR } from '../../actions/fetchActions';
+import { hideNotification } from '../../actions/notificationActions';

 export default function* () {
     yield takeEvery(FETCH_ERROR, function* redirectIfNotauthenticated({ error }) {
         if (error.status === 401 || error.status === 403) {
+            yield put(hideNotification());
             yield put(push('/login'));
         }
     });

<|original_code|>
import { put, takeEvery } from 'redux-saga/effects';
import { push } from 'react-router-redux';
import { FETCH_ERROR } from '../../actions/fetchActions';

export default function* () {
    yield takeEvery(FETCH_ERROR, function* redirectIfNotauthenticated({ error }) {
        if (error.status === 401 || error.status === 403) {
            yield put(push('/login'));
        }
    });
}

<|edits_diff|>
--- src/sideEffect/saga/auth.js
+++ src/sideEffect/saga/auth.js
@@ -1,6 +1,7 @@
 import { put, takeEvery } from 'redux-saga/effects';
 import { push } from 'react-router-redux';
 import { FETCH_ERROR } from '../../actions/fetchActions';
+import { hideNotification } from '../../actions/notificationActions';

 export default function* () {
     yield takeEvery(FETCH_ERROR, function* redirectIfNotauthenticated({ error }) {
<|current_version|>
import { put, takeEvery } from 'redux-saga/effects';
import { push } from 'react-router-redux';
import { FETCH_ERROR } from '../../actions/fetchActions';
import { hideNotification } from '../../actions/notificationActions';

export default function* () {
    yield takeEvery(FETCH_ERROR, function* redirectIfNotauthenticated({ error }) {
        if (error.status === 401 || error.status === 403) {
            yield put(push('/login'));
        }
    });
}

<|next_version|>
import { put, takeEvery } from 'redux-saga/effects';
import { push } from 'react-router-redux';
import { FETCH_ERROR } from '../../actions/fetchActions';
import { hideNotification } from '../../actions/notificationActions';

export default function* () {
    yield takeEvery(FETCH_ERROR, function* redirectIfNotauthenticated({ error }) {
        if (error.status === 401 || error.status === 403) {
            yield put(hideNotification());
            yield put(push('/login'));
        }
    });
}


Use storyshots renderer option to use enzyme

--- examples/cra-kitchen-sink/src/storyshots.test.js
+++ examples/cra-kitchen-sink/src/storyshots.test.js
@@ -1,5 +1,6 @@
 import initStoryshots, { multiSnapshotWithOptions } from '@storybook/addon-storyshots';
 import path from 'path';
+import { mount as renderer } from 'enzyme';

 function createNodeMock(element) {
   if (element.type === 'div') {
@@ -13,5 +14,6 @@
   configPath: path.join(__dirname, '..', '.storybook'),
   test: multiSnapshotWithOptions({
     createNodeMock,
+    renderer,
   }),
 });

<|original_code|>
import initStoryshots, { multiSnapshotWithOptions } from '@storybook/addon-storyshots';
import path from 'path';

function createNodeMock(element) {
  if (element.type === 'div') {
    return { scrollWidth: 123 };
  }
  return null;
}

initStoryshots({
  framework: 'react',
  configPath: path.join(__dirname, '..', '.storybook'),
  test: multiSnapshotWithOptions({
    createNodeMock,
  }),
});

<|edits_diff|>
--- examples/cra-kitchen-sink/src/storyshots.test.js
+++ examples/cra-kitchen-sink/src/storyshots.test.js
@@ -1,5 +1,6 @@
 import initStoryshots, { multiSnapshotWithOptions } from '@storybook/addon-storyshots';
 import path from 'path';
+import { mount as renderer } from 'enzyme';

 function createNodeMock(element) {
   if (element.type === 'div') {
<|current_version|>
import initStoryshots, { multiSnapshotWithOptions } from '@storybook/addon-storyshots';
import path from 'path';
import { mount as renderer } from 'enzyme';

function createNodeMock(element) {
  if (element.type === 'div') {
    return { scrollWidth: 123 };
  }
  return null;
}

initStoryshots({
  framework: 'react',
  configPath: path.join(__dirname, '..', '.storybook'),
  test: multiSnapshotWithOptions({
    createNodeMock,
  }),
});

<|next_version|>
import initStoryshots, { multiSnapshotWithOptions } from '@storybook/addon-storyshots';
import path from 'path';
import { mount as renderer } from 'enzyme';

function createNodeMock(element) {
  if (element.type === 'div') {
    return { scrollWidth: 123 };
  }
  return null;
}

initStoryshots({
  framework: 'react',
  configPath: path.join(__dirname, '..', '.storybook'),
  test: multiSnapshotWithOptions({
    createNodeMock,
    renderer,
  }),
});


Fix problem with system sending empty answers

Some web browsers do not trigger the keyup or keydown events.
One of those web browsers is BluStar Agent.
This caused the system to think nothing had been entered into the fields.

Solve this problem by both listenting to change and keyup event.

--- Public/Support/Components/Textfield/Textfield.js
+++ Public/Support/Components/Textfield/Textfield.js
@@ -3,8 +3,12 @@

 	self.setDefaultState('text-value');
 	self.bind = function() {
+		self.attachChangeAction( self.node(), self.identifier() );
 		self.attachKeyUpAction( self.node(), self.identifier() );
 	};
+	self.registerAction('change', function() {
+		self.setState('text-value', self.node().value);
+	});
 	self.registerAction('keyup', function() {
 		self._states['text-value'] = self.node().value;
 	});

<|original_code|>
function ComponentTextfield( id ) {
	var self = _ComponentFormControl(id);

	self.setDefaultState('text-value');
	self.bind = function() {
		self.attachKeyUpAction( self.node(), self.identifier() );
	};
	self.registerAction('keyup', function() {
		self._states['text-value'] = self.node().value;
	});
	self.select = function() {
		if( self.node() ) {
			self.node().select();
		}
	};
	self.textValue = function() {
		self.setState('text-value', self.node().value);
		return self.getState('text-value');
	};
	self.setTextValue = function( value ) {
		self.setState('text-value', value);
		self.node().value = value;
	};
	self.enable = function() {
		self._enabled = true;
		self.node().readOnly = false;
	};
	self.disable = function() {
		self._enabled = false;
		self.node().readOnly = true;
	};
	return self;
}

<|edits_diff|>
--- Public/Support/Components/Textfield/Textfield.js
+++ Public/Support/Components/Textfield/Textfield.js
@@ -3,6 +3,7 @@

 	self.setDefaultState('text-value');
 	self.bind = function() {
+		self.attachChangeAction( self.node(), self.identifier() );
 		self.attachKeyUpAction( self.node(), self.identifier() );
 	};
 	self.registerAction('keyup', function() {
<|current_version|>
function ComponentTextfield( id ) {
	var self = _ComponentFormControl(id);

	self.setDefaultState('text-value');
	self.bind = function() {
		self.attachChangeAction( self.node(), self.identifier() );
		self.attachKeyUpAction( self.node(), self.identifier() );
	};
	self.registerAction('keyup', function() {
		self._states['text-value'] = self.node().value;
	});
	self.select = function() {
		if( self.node() ) {
			self.node().select();
		}
	};
	self.textValue = function() {
		self.setState('text-value', self.node().value);
		return self.getState('text-value');
	};
	self.setTextValue = function( value ) {
		self.setState('text-value', value);
		self.node().value = value;
	};
	self.enable = function() {
		self._enabled = true;
		self.node().readOnly = false;
	};
	self.disable = function() {
		self._enabled = false;
		self.node().readOnly = true;
	};
	return self;
}

<|next_version|>
function ComponentTextfield( id ) {
	var self = _ComponentFormControl(id);

	self.setDefaultState('text-value');
	self.bind = function() {
		self.attachChangeAction( self.node(), self.identifier() );
		self.attachKeyUpAction( self.node(), self.identifier() );
	};
	self.registerAction('change', function() {
		self.setState('text-value', self.node().value);
	});
	self.registerAction('keyup', function() {
		self._states['text-value'] = self.node().value;
	});
	self.select = function() {
		if( self.node() ) {
			self.node().select();
		}
	};
	self.textValue = function() {
		self.setState('text-value', self.node().value);
		return self.getState('text-value');
	};
	self.setTextValue = function( value ) {
		self.setState('text-value', value);
		self.node().value = value;
	};
	self.enable = function() {
		self._enabled = true;
		self.node().readOnly = false;
	};
	self.disable = function() {
		self._enabled = false;
		self.node().readOnly = true;
	};
	return self;
}


Fix tests failure on PR

Fix tests failure on PR

--- build/run_tests.js
+++ build/run_tests.js
@@ -4,10 +4,22 @@
 require('shelljs/global');
 set('-e');

+function isPR() {
+  return process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== 'false';
+}
+
 if (process.env.JOB === 'e2e-guru') {
+  if (isPR()) {
+    console.log('Skiping E2E tests on PR');
+    return;
+  }
   exec('npm run e2e');
 } else {
   exec('npm run unit');
+  if (isPR()) {
+    console.log('Skiping E2E tests on PR');
+    return;
+  }
   console.log('Starting Basic E2E');
   exec('npm run e2e');
 }

<|original_code|>
#!/usr/bin/env node
'use strict';

require('shelljs/global');
set('-e');

if (process.env.JOB === 'e2e-guru') {
  exec('npm run e2e');
} else {
  exec('npm run unit');
  console.log('Starting Basic E2E');
  exec('npm run e2e');
}

<|edits_diff|>
--- build/run_tests.js
+++ build/run_tests.js
@@ -4,7 +4,15 @@
 require('shelljs/global');
 set('-e');

+function isPR() {
+  return process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== 'false';
+}
+
 if (process.env.JOB === 'e2e-guru') {
+  if (isPR()) {
+    console.log('Skiping E2E tests on PR');
+    return;
+  }
   exec('npm run e2e');
 } else {
   exec('npm run unit');
<|current_version|>
#!/usr/bin/env node
'use strict';

require('shelljs/global');
set('-e');

function isPR() {
  return process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== 'false';
}

if (process.env.JOB === 'e2e-guru') {
  if (isPR()) {
    console.log('Skiping E2E tests on PR');
    return;
  }
  exec('npm run e2e');
} else {
  exec('npm run unit');
  console.log('Starting Basic E2E');
  exec('npm run e2e');
}

<|next_version|>
#!/usr/bin/env node
'use strict';

require('shelljs/global');
set('-e');

function isPR() {
  return process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== 'false';
}

if (process.env.JOB === 'e2e-guru') {
  if (isPR()) {
    console.log('Skiping E2E tests on PR');
    return;
  }
  exec('npm run e2e');
} else {
  exec('npm run unit');
  if (isPR()) {
    console.log('Skiping E2E tests on PR');
    return;
  }
  console.log('Starting Basic E2E');
  exec('npm run e2e');
}


Enable cache for all endpoints

Enable cache for all endpoints

--- species-explorer/app/services/species.service.js
+++ species-explorer/app/services/species.service.js
@@ -16,6 +16,7 @@
       getKingdoms: {
         method: 'GET',
         isArray: false,
+        cache: true,
         params: {
           op: 'getkingdomnames'
         }
@@ -23,6 +24,7 @@
       getClasses: {
         method: 'GET',
         isArray: false,
+        cache: true,
         params: {
           op: 'getclassnames'
         }
@@ -30,6 +32,7 @@
       getFamilies: {
         method: 'GET',
         isArray: false,
+        cache: true,
         params: {
           op: 'getfamilynames'
         }

<|original_code|>
/* global angular */

angular
  .module('speciesApp')
  .factory('SpeciesService', [
    'API_BASE_URL',
    '$resource',
    SpeciesService
  ])

function SpeciesService (API_BASE_URL, $resource) {
  return $resource(
    API_BASE_URL,
    null,
    {
      getKingdoms: {
        method: 'GET',
        isArray: false,
        params: {
          op: 'getkingdomnames'
        }
      },
      getClasses: {
        method: 'GET',
        isArray: false,
        params: {
          op: 'getclassnames'
        }
      },
      getFamilies: {
        method: 'GET',
        isArray: false,
        params: {
          op: 'getfamilynames'
        }
      }
    }
  )
}

<|edits_diff|>
--- species-explorer/app/services/species.service.js
+++ species-explorer/app/services/species.service.js
@@ -16,6 +16,7 @@
       getKingdoms: {
         method: 'GET',
         isArray: false,
+        cache: true,
         params: {
           op: 'getkingdomnames'
         }
@@ -23,6 +24,7 @@
       getClasses: {
         method: 'GET',
         isArray: false,
+        cache: true,
         params: {
           op: 'getclassnames'
         }
<|current_version|>
/* global angular */

angular
  .module('speciesApp')
  .factory('SpeciesService', [
    'API_BASE_URL',
    '$resource',
    SpeciesService
  ])

function SpeciesService (API_BASE_URL, $resource) {
  return $resource(
    API_BASE_URL,
    null,
    {
      getKingdoms: {
        method: 'GET',
        isArray: false,
        cache: true,
        params: {
          op: 'getkingdomnames'
        }
      },
      getClasses: {
        method: 'GET',
        isArray: false,
        cache: true,
        params: {
          op: 'getclassnames'
        }
      },
      getFamilies: {
        method: 'GET',
        isArray: false,
        params: {
          op: 'getfamilynames'
        }
      }
    }
  )
}

<|next_version|>
/* global angular */

angular
  .module('speciesApp')
  .factory('SpeciesService', [
    'API_BASE_URL',
    '$resource',
    SpeciesService
  ])

function SpeciesService (API_BASE_URL, $resource) {
  return $resource(
    API_BASE_URL,
    null,
    {
      getKingdoms: {
        method: 'GET',
        isArray: false,
        cache: true,
        params: {
          op: 'getkingdomnames'
        }
      },
      getClasses: {
        method: 'GET',
        isArray: false,
        cache: true,
        params: {
          op: 'getclassnames'
        }
      },
      getFamilies: {
        method: 'GET',
        isArray: false,
        cache: true,
        params: {
          op: 'getfamilynames'
        }
      }
    }
  )
}


Enable new flowtype eslint rules

Enable new flowtype eslint rules

There have been some new rules added since we started using this plugin.
It looks like we are already following them, so no additional cleanup is
needed.

--- .eslintrc.js
+++ .eslintrc.js
@@ -21,14 +21,19 @@
     'no-underscore-dangle': ['error', { allowAfterThis: true }],

     'flowtype/define-flow-type': 2,
+    'flowtype/generic-spacing': [2, 'never'],
     'flowtype/require-parameter-type': 2,
     'flowtype/require-return-type': [2, 'always', {
       annotateUndefined: 'never'
     }],
+    'flowtype/require-valid-file-annotation': [2, 'always'],
     'flowtype/space-after-type-colon': [2, 'always'],
     'flowtype/space-before-type-colon': [2, 'never'],
+    'flowtype/space-before-generic-bracket': [2, 'never'],
+    'flowtype/union-intersection-spacing': [2, 'always'],
     'flowtype/type-id-match': [2, "^([A-Z][a-z0-9]+)+Type$"],
     'flowtype/use-flow-type': 2,
+    'flowtype/valid-syntax': 2,
   },

   settings: {

<|original_code|>
module.exports = {
  parser: 'babel-eslint',

  plugins: [
    'flowtype',

    // Although we don't have any React or JSX in this project, we need to have
    // this plugin and some of the rules from this plugin enabled here so that
    // our tests work. We should probably look into a way of doing this so that
    // this configuration is scoped specifically for the tests that require it.
    'react',
  ],

  extends: [
    'airbnb-base',
    'plugin:react/recommended',
  ],

  rules: {
    'no-shadow': 0, // This is currently erroring because of flow type defs
    'no-underscore-dangle': ['error', { allowAfterThis: true }],

    'flowtype/define-flow-type': 2,
    'flowtype/require-parameter-type': 2,
    'flowtype/require-return-type': [2, 'always', {
      annotateUndefined: 'never'
    }],
    'flowtype/space-after-type-colon': [2, 'always'],
    'flowtype/space-before-type-colon': [2, 'never'],
    'flowtype/type-id-match': [2, "^([A-Z][a-z0-9]+)+Type$"],
    'flowtype/use-flow-type': 2,
  },

  settings: {
    flowtype: {
      onlyFilesWithFlowAnnotation: true,
    },
  },
};

<|edits_diff|>
--- .eslintrc.js
+++ .eslintrc.js
@@ -21,12 +21,16 @@
     'no-underscore-dangle': ['error', { allowAfterThis: true }],

     'flowtype/define-flow-type': 2,
+    'flowtype/generic-spacing': [2, 'never'],
     'flowtype/require-parameter-type': 2,
     'flowtype/require-return-type': [2, 'always', {
       annotateUndefined: 'never'
     }],
+    'flowtype/require-valid-file-annotation': [2, 'always'],
     'flowtype/space-after-type-colon': [2, 'always'],
     'flowtype/space-before-type-colon': [2, 'never'],
+    'flowtype/space-before-generic-bracket': [2, 'never'],
+    'flowtype/union-intersection-spacing': [2, 'always'],
     'flowtype/type-id-match': [2, "^([A-Z][a-z0-9]+)+Type$"],
     'flowtype/use-flow-type': 2,
   },
<|current_version|>
module.exports = {
  parser: 'babel-eslint',

  plugins: [
    'flowtype',

    // Although we don't have any React or JSX in this project, we need to have
    // this plugin and some of the rules from this plugin enabled here so that
    // our tests work. We should probably look into a way of doing this so that
    // this configuration is scoped specifically for the tests that require it.
    'react',
  ],

  extends: [
    'airbnb-base',
    'plugin:react/recommended',
  ],

  rules: {
    'no-shadow': 0, // This is currently erroring because of flow type defs
    'no-underscore-dangle': ['error', { allowAfterThis: true }],

    'flowtype/define-flow-type': 2,
    'flowtype/generic-spacing': [2, 'never'],
    'flowtype/require-parameter-type': 2,
    'flowtype/require-return-type': [2, 'always', {
      annotateUndefined: 'never'
    }],
    'flowtype/require-valid-file-annotation': [2, 'always'],
    'flowtype/space-after-type-colon': [2, 'always'],
    'flowtype/space-before-type-colon': [2, 'never'],
    'flowtype/space-before-generic-bracket': [2, 'never'],
    'flowtype/union-intersection-spacing': [2, 'always'],
    'flowtype/type-id-match': [2, "^([A-Z][a-z0-9]+)+Type$"],
    'flowtype/use-flow-type': 2,
  },

  settings: {
    flowtype: {
      onlyFilesWithFlowAnnotation: true,
    },
  },
};

<|next_version|>
module.exports = {
  parser: 'babel-eslint',

  plugins: [
    'flowtype',

    // Although we don't have any React or JSX in this project, we need to have
    // this plugin and some of the rules from this plugin enabled here so that
    // our tests work. We should probably look into a way of doing this so that
    // this configuration is scoped specifically for the tests that require it.
    'react',
  ],

  extends: [
    'airbnb-base',
    'plugin:react/recommended',
  ],

  rules: {
    'no-shadow': 0, // This is currently erroring because of flow type defs
    'no-underscore-dangle': ['error', { allowAfterThis: true }],

    'flowtype/define-flow-type': 2,
    'flowtype/generic-spacing': [2, 'never'],
    'flowtype/require-parameter-type': 2,
    'flowtype/require-return-type': [2, 'always', {
      annotateUndefined: 'never'
    }],
    'flowtype/require-valid-file-annotation': [2, 'always'],
    'flowtype/space-after-type-colon': [2, 'always'],
    'flowtype/space-before-type-colon': [2, 'never'],
    'flowtype/space-before-generic-bracket': [2, 'never'],
    'flowtype/union-intersection-spacing': [2, 'always'],
    'flowtype/type-id-match': [2, "^([A-Z][a-z0-9]+)+Type$"],
    'flowtype/use-flow-type': 2,
    'flowtype/valid-syntax': 2,
  },

  settings: {
    flowtype: {
      onlyFilesWithFlowAnnotation: true,
    },
  },
};


Add route to 404 page

Add route to 404 page

--- client/router.js
+++ client/router.js
@@ -2,6 +2,7 @@
 import Router from 'vue-router'
 import Index from '@/views/Index'
 import Group from '@/views/Group'
+import NotFound from '@/views/NotFound'

 Vue.use(Router)

@@ -24,5 +25,10 @@
       alias: '/group/:groupId',
       props: true,
     },
+    {
+      path: '/*',
+      name: 'not-found',
+      component: NotFound,
+    },
   ],
 })

<|original_code|>
import Vue from 'vue'
import Router from 'vue-router'
import Index from '@/views/Index'
import Group from '@/views/Group'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'index',
      component: Index,
    },
    {
      path: '/group/:groupId',
      name: 'group',
      component: Group,
      props: true,
    },
    {
      path: '/group/:groupId/:groupName',
      component: Group,
      alias: '/group/:groupId',
      props: true,
    },
  ],
})

<|edits_diff|>
--- client/router.js
+++ client/router.js
@@ -2,6 +2,7 @@
 import Router from 'vue-router'
 import Index from '@/views/Index'
 import Group from '@/views/Group'
+import NotFound from '@/views/NotFound'

 Vue.use(Router)

<|current_version|>
import Vue from 'vue'
import Router from 'vue-router'
import Index from '@/views/Index'
import Group from '@/views/Group'
import NotFound from '@/views/NotFound'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'index',
      component: Index,
    },
    {
      path: '/group/:groupId',
      name: 'group',
      component: Group,
      props: true,
    },
    {
      path: '/group/:groupId/:groupName',
      component: Group,
      alias: '/group/:groupId',
      props: true,
    },
  ],
})

<|next_version|>
import Vue from 'vue'
import Router from 'vue-router'
import Index from '@/views/Index'
import Group from '@/views/Group'
import NotFound from '@/views/NotFound'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'index',
      component: Index,
    },
    {
      path: '/group/:groupId',
      name: 'group',
      component: Group,
      props: true,
    },
    {
      path: '/group/:groupId/:groupName',
      component: Group,
      alias: '/group/:groupId',
      props: true,
    },
    {
      path: '/*',
      name: 'not-found',
      component: NotFound,
    },
  ],
})


Add link to go back to index

Add link to go back to index

--- src/components/posts_show.js
+++ src/components/posts_show.js
@@ -1,5 +1,6 @@
 import React, { Component } from 'react';
 import { connect } from 'react-redux';
+import { Link } from 'react-router-dom';
 import { fetchPost } from '../actions';

 class PostsShow extends Component {
@@ -17,6 +18,7 @@

     return (

+        <Link to="/">Back To Index</Link>

{post.title}

Categories: {post.categories}

{post.content}

<|original_code|>
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchPost } from '../actions';

class PostsShow extends Component {
  componentDidMount() {
    const { id } = this.props.match.params;
    this.props.fetchPost(id);
  }

  render() {
    const { post } = this.props;

    if (!post) {
      return
Loading...
;
    }

    return (

{post.title}

Categories: {post.categories}

{post.content}

    );
  }
}

function mapStateToProps({ posts }, ownProps) {
  return { post: posts[ownProps.match.params.id] };
}

export default connect(mapStateToProps, { fetchPost })(PostsShow);

<|edits_diff|>
--- src/components/posts_show.js
+++ src/components/posts_show.js
@@ -1,5 +1,6 @@
 import React, { Component } from 'react';
 import { connect } from 'react-redux';
+import { Link } from 'react-router-dom';
 import { fetchPost } from '../actions';

 class PostsShow extends Component {
<|current_version|>
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { fetchPost } from '../actions';

class PostsShow extends Component {
  componentDidMount() {
    const { id } = this.props.match.params;
    this.props.fetchPost(id);
  }

  render() {
    const { post } = this.props;

    if (!post) {
      return
Loading...
;
    }

    return (

{post.title}

Categories: {post.categories}

{post.content}

    );
  }
}

function mapStateToProps({ posts }, ownProps) {
  return { post: posts[ownProps.match.params.id] };
}

export default connect(mapStateToProps, { fetchPost })(PostsShow);

<|next_version|>
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { fetchPost } from '../actions';

class PostsShow extends Component {
  componentDidMount() {
    const { id } = this.props.match.params;
    this.props.fetchPost(id);
  }

  render() {
    const { post } = this.props;

    if (!post) {
      return
Loading...
;
    }

    return (

        <Link to="/">Back To Index</Link>

{post.title}

Categories: {post.categories}

{post.content}

    );
  }
}

function mapStateToProps({ posts }, ownProps) {
  return { post: posts[ownProps.match.params.id] };
}

export default connect(mapStateToProps, { fetchPost })(PostsShow);


Add SearchButton component to Header component

--- app/components/Header/index.js
+++ app/components/Header/index.js
@@ -2,6 +2,7 @@
 import styled from 'styled-components';
 import theme from 'theme';
 import Hamburger, { Bar } from 'components/Hamburger';
+import SearchButton from 'components/SearchButton';

 const Logo = styled.h1`
     font-family: Poppins, sans-serif;
@@ -44,6 +45,9 @@
                     <Hamburger />
                 </MenuButton>
                 <Logo>MMDb</Logo>
+                <MenuButton>
+                    <SearchButton />
+                </MenuButton>
             </StyledHeader>
         );
     }

<|original_code|>
import React from 'react';
import styled from 'styled-components';
import theme from 'theme';
import Hamburger, { Bar } from 'components/Hamburger';

const Logo = styled.h1`
    font-family: Poppins, sans-serif;
    letter-spacing: 1px;
    font-size: 30px;
    margin: 0;
    display: inline;
    flex: 0 0 calc(100% - 130px);
    text-align: center;
`;
const MenuButton = styled.div`
    display: inline-flex;
    cursor: pointer;
    justify-content: center;
    align-items: center;
    height: 100%;
    width: 65px;
    border-right: 1px solid ${theme.lightGray};
    flex: 0 0 65px;
    &:hover {
        ${Bar} {
            &::after {
                left: 0;
            }
        }
    }
`;
const StyledHeader = styled.header`
    border-bottom: 1px solid ${theme.lightGray};
    height: 70px;
    display: flex;
    align-items: center;
`;

class Header extends React.PureComponent {
    render() {
        return (
            <StyledHeader role="banner">
                <MenuButton>
                    <Hamburger />
                </MenuButton>
                <Logo>MMDb</Logo>
            </StyledHeader>
        );
    }
}

Header.propTypes = {

};

export default Header;

<|edits_diff|>
--- app/components/Header/index.js
+++ app/components/Header/index.js
@@ -2,6 +2,7 @@
 import styled from 'styled-components';
 import theme from 'theme';
 import Hamburger, { Bar } from 'components/Hamburger';
+import SearchButton from 'components/SearchButton';

 const Logo = styled.h1`
     font-family: Poppins, sans-serif;
<|current_version|>
import React from 'react';
import styled from 'styled-components';
import theme from 'theme';
import Hamburger, { Bar } from 'components/Hamburger';
import SearchButton from 'components/SearchButton';

const Logo = styled.h1`
    font-family: Poppins, sans-serif;
    letter-spacing: 1px;
    font-size: 30px;
    margin: 0;
    display: inline;
    flex: 0 0 calc(100% - 130px);
    text-align: center;
`;
const MenuButton = styled.div`
    display: inline-flex;
    cursor: pointer;
    justify-content: center;
    align-items: center;
    height: 100%;
    width: 65px;
    border-right: 1px solid ${theme.lightGray};
    flex: 0 0 65px;
    &:hover {
        ${Bar} {
            &::after {
                left: 0;
            }
        }
    }
`;
const StyledHeader = styled.header`
    border-bottom: 1px solid ${theme.lightGray};
    height: 70px;
    display: flex;
    align-items: center;
`;

class Header extends React.PureComponent {
    render() {
        return (
            <StyledHeader role="banner">
                <MenuButton>
                    <Hamburger />
                </MenuButton>
                <Logo>MMDb</Logo>
            </StyledHeader>
        );
    }
}

Header.propTypes = {

};

export default Header;

<|next_version|>
import React from 'react';
import styled from 'styled-components';
import theme from 'theme';
import Hamburger, { Bar } from 'components/Hamburger';
import SearchButton from 'components/SearchButton';

const Logo = styled.h1`
    font-family: Poppins, sans-serif;
    letter-spacing: 1px;
    font-size: 30px;
    margin: 0;
    display: inline;
    flex: 0 0 calc(100% - 130px);
    text-align: center;
`;
const MenuButton = styled.div`
    display: inline-flex;
    cursor: pointer;
    justify-content: center;
    align-items: center;
    height: 100%;
    width: 65px;
    border-right: 1px solid ${theme.lightGray};
    flex: 0 0 65px;
    &:hover {
        ${Bar} {
            &::after {
                left: 0;
            }
        }
    }
`;
const StyledHeader = styled.header`
    border-bottom: 1px solid ${theme.lightGray};
    height: 70px;
    display: flex;
    align-items: center;
`;

class Header extends React.PureComponent {
    render() {
        return (
            <StyledHeader role="banner">
                <MenuButton>
                    <Hamburger />
                </MenuButton>
                <Logo>MMDb</Logo>
                <MenuButton>
                    <SearchButton />
                </MenuButton>
            </StyledHeader>
        );
    }
}

Header.propTypes = {

};

export default Header;


Add comments back to file

Add comments back to file

--- blueprints/sl-ember-test-helpers/index.js
+++ blueprints/sl-ember-test-helpers/index.js
@@ -21,14 +21,19 @@
         var thirdText = '    "contains",' + EOL + '    "requires",';
         var thirdLocationText = '"predef": [' + EOL;

+        // Import statement
         return this.insertIntoFile( firstFile, firstText, { after: firstLocationText } )
+
             // Execution of registration function
             .then( function() {
                 return this.insertIntoFile( secondFile, secondText, { after: secondLocationText } );
             }.bind( this ))
+
+            // .jshintrc file
             .then( function() {
                 return this.insertIntoFile( thirdFile, thirdText, { after: thirdLocationText } );
             }.bind( this ))
+
             .then( function() {
                 return this.addAddonToProject( 'ember-sinon' );
             }.bind( this ));

<|original_code|>
/* globals module */

var EOL = require('os').EOL;

module.exports = {
    description: 'Register test helpers',

    afterInstall: function( options ) {
        // Import statement
        var firstFile = 'tests/helpers/start-app.js';
        var firstText = "import slRegisterTestHelpers from './sl/register-test-helpers';";
        var firstLocationText = "import Ember from 'ember';" + EOL;

        // Execution of registration function
        var secondFile = 'tests/helpers/start-app.js';
        var secondText = "    slRegisterTestHelpers();";
        var secondLocationText = "application.setupForTesting();" + EOL;

        // .jshintrc file
        var thirdFile = 'tests/.jshintrc';
        var thirdText = '    "contains",' + EOL + '    "requires",';
        var thirdLocationText = '"predef": [' + EOL;

        return this.insertIntoFile( firstFile, firstText, { after: firstLocationText } )
            // Execution of registration function
            .then( function() {
                return this.insertIntoFile( secondFile, secondText, { after: secondLocationText } );
            }.bind( this ))
            .then( function() {
                return this.insertIntoFile( thirdFile, thirdText, { after: thirdLocationText } );
            }.bind( this ))
            .then( function() {
                return this.addAddonToProject( 'ember-sinon' );
            }.bind( this ));
    },

    normalizeEntityName: function() {}
};

<|edits_diff|>
--- blueprints/sl-ember-test-helpers/index.js
+++ blueprints/sl-ember-test-helpers/index.js
@@ -21,11 +21,15 @@
         var thirdText = '    "contains",' + EOL + '    "requires",';
         var thirdLocationText = '"predef": [' + EOL;

+        // Import statement
         return this.insertIntoFile( firstFile, firstText, { after: firstLocationText } )
+
             // Execution of registration function
             .then( function() {
                 return this.insertIntoFile( secondFile, secondText, { after: secondLocationText } );
             }.bind( this ))
+
+            // .jshintrc file
             .then( function() {
                 return this.insertIntoFile( thirdFile, thirdText, { after: thirdLocationText } );
             }.bind( this ))
<|current_version|>
/* globals module */

var EOL = require('os').EOL;

module.exports = {
    description: 'Register test helpers',

    afterInstall: function( options ) {
        // Import statement
        var firstFile = 'tests/helpers/start-app.js';
        var firstText = "import slRegisterTestHelpers from './sl/register-test-helpers';";
        var firstLocationText = "import Ember from 'ember';" + EOL;

        // Execution of registration function
        var secondFile = 'tests/helpers/start-app.js';
        var secondText = "    slRegisterTestHelpers();";
        var secondLocationText = "application.setupForTesting();" + EOL;

        // .jshintrc file
        var thirdFile = 'tests/.jshintrc';
        var thirdText = '    "contains",' + EOL + '    "requires",';
        var thirdLocationText = '"predef": [' + EOL;

        // Import statement
        return this.insertIntoFile( firstFile, firstText, { after: firstLocationText } )

            // Execution of registration function
            .then( function() {
                return this.insertIntoFile( secondFile, secondText, { after: secondLocationText } );
            }.bind( this ))

            // .jshintrc file
            .then( function() {
                return this.insertIntoFile( thirdFile, thirdText, { after: thirdLocationText } );
            }.bind( this ))
            .then( function() {
                return this.addAddonToProject( 'ember-sinon' );
            }.bind( this ));
    },

    normalizeEntityName: function() {}
};

<|next_version|>
/* globals module */

var EOL = require('os').EOL;

module.exports = {
    description: 'Register test helpers',

    afterInstall: function( options ) {
        // Import statement
        var firstFile = 'tests/helpers/start-app.js';
        var firstText = "import slRegisterTestHelpers from './sl/register-test-helpers';";
        var firstLocationText = "import Ember from 'ember';" + EOL;

        // Execution of registration function
        var secondFile = 'tests/helpers/start-app.js';
        var secondText = "    slRegisterTestHelpers();";
        var secondLocationText = "application.setupForTesting();" + EOL;

        // .jshintrc file
        var thirdFile = 'tests/.jshintrc';
        var thirdText = '    "contains",' + EOL + '    "requires",';
        var thirdLocationText = '"predef": [' + EOL;

        // Import statement
        return this.insertIntoFile( firstFile, firstText, { after: firstLocationText } )

            // Execution of registration function
            .then( function() {
                return this.insertIntoFile( secondFile, secondText, { after: secondLocationText } );
            }.bind( this ))

            // .jshintrc file
            .then( function() {
                return this.insertIntoFile( thirdFile, thirdText, { after: thirdLocationText } );
            }.bind( this ))

            .then( function() {
                return this.addAddonToProject( 'ember-sinon' );
            }.bind( this ));
    },

    normalizeEntityName: function() {}
};


Revert "Revert "Revert "Revert "Try child process""""

This reverts commit 59eec97713488c95c2e8869e8b73ce0d0eab09bb.

--- plugin.js
+++ plugin.js
@@ -1,5 +1,8 @@
+const { spawn } = require('child_process')
+
 module.exports = {
   onPreBuild({ utils: { status: { show } } }) {
+    spawn('sleep', ['60'], { detached: true })
     show({ summary: 'Test' })
   }
 }

<|original_code|>
module.exports = {
  onPreBuild({ utils: { status: { show } } }) {
    show({ summary: 'Test' })
  }
}

<|edits_diff|>
--- plugin.js
+++ plugin.js
@@ -1,3 +1,5 @@
+const { spawn } = require('child_process')
+
 module.exports = {
   onPreBuild({ utils: { status: { show } } }) {
     show({ summary: 'Test' })
<|current_version|>
const { spawn } = require('child_process')

module.exports = {
  onPreBuild({ utils: { status: { show } } }) {
    show({ summary: 'Test' })
  }
}

<|next_version|>
const { spawn } = require('child_process')

module.exports = {
  onPreBuild({ utils: { status: { show } } }) {
    spawn('sleep', ['60'], { detached: true })
    show({ summary: 'Test' })
  }
}


Add missing exports for backwardConnectionArgs and forwardConnectionArgs

--- src/index.js
+++ src/index.js
@@ -9,8 +9,10 @@

 // Helpers for creating connection types in the schema
 export {
+  backwardConnectionArgs,
   connectionArgs,
   connectionDefinitions,
+  forwardConnectionArgs,
 } from './connection/connection.js';

 // Helpers for creating connections from arrays

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

// Helpers for creating connection types in the schema
export {
  connectionArgs,
  connectionDefinitions,
} from './connection/connection.js';

// Helpers for creating connections from arrays
export {
  connectionFromArray,
  connectionFromArraySlice,
  connectionFromPromisedArray,
  connectionFromPromisedArraySlice,
  cursorForObjectInConnection,
  cursorToOffset,
  getOffsetWithDefault,
  offsetToCursor,
} from './connection/arrayconnection.js';

// Helper for creating mutations with client mutation IDs
export {
  mutationWithClientMutationId,
} from './mutation/mutation.js';

// Helper for creating node definitions
export {
  nodeDefinitions,
} from './node/node.js';

// Utilities for creating global IDs in systems that don't have them.
export {
  fromGlobalId,
  globalIdField,
  toGlobalId,
} from './node/node.js';

<|edits_diff|>
--- src/index.js
+++ src/index.js
@@ -9,6 +9,7 @@

 // Helpers for creating connection types in the schema
 export {
+  backwardConnectionArgs,
   connectionArgs,
   connectionDefinitions,
 } from './connection/connection.js';
<|current_version|>
/**
 *  Copyright (c) 2015, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 */

// Helpers for creating connection types in the schema
export {
  backwardConnectionArgs,
  connectionArgs,
  connectionDefinitions,
} from './connection/connection.js';

// Helpers for creating connections from arrays
export {
  connectionFromArray,
  connectionFromArraySlice,
  connectionFromPromisedArray,
  connectionFromPromisedArraySlice,
  cursorForObjectInConnection,
  cursorToOffset,
  getOffsetWithDefault,
  offsetToCursor,
} from './connection/arrayconnection.js';

// Helper for creating mutations with client mutation IDs
export {
  mutationWithClientMutationId,
} from './mutation/mutation.js';

// Helper for creating node definitions
export {
  nodeDefinitions,
} from './node/node.js';

// Utilities for creating global IDs in systems that don't have them.
export {
  fromGlobalId,
  globalIdField,
  toGlobalId,
} from './node/node.js';

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

// Helpers for creating connection types in the schema
export {
  backwardConnectionArgs,
  connectionArgs,
  connectionDefinitions,
  forwardConnectionArgs,
} from './connection/connection.js';

// Helpers for creating connections from arrays
export {
  connectionFromArray,
  connectionFromArraySlice,
  connectionFromPromisedArray,
  connectionFromPromisedArraySlice,
  cursorForObjectInConnection,
  cursorToOffset,
  getOffsetWithDefault,
  offsetToCursor,
} from './connection/arrayconnection.js';

// Helper for creating mutations with client mutation IDs
export {
  mutationWithClientMutationId,
} from './mutation/mutation.js';

// Helper for creating node definitions
export {
  nodeDefinitions,
} from './node/node.js';

// Utilities for creating global IDs in systems that don't have them.
export {
  fromGlobalId,
  globalIdField,
  toGlobalId,
} from './node/node.js';


Set NODE_ENV correctly in prod to speed up React

--- src/renderer/generic/index.js
+++ src/renderer/generic/index.js
@@ -1,3 +1,4 @@
+import { remote } from 'electron';
 import '../rendererEmitter';
 import './core';

@@ -12,6 +13,8 @@

 require(`./${process.platform}`);
 require('./translations');
+
+process.env['NODE_ENV'] = remote.getGlobal('DEV_MODE') ? 'development' : 'production';

 document.addEventListener('DOMContentLoaded', () => {
   require('./windowThemeHandler');

<|original_code|>
import '../rendererEmitter';
import './core';

import SettingsController from '../../main/utils/Settings';

if (process.env['TEST_SPEC']) { // eslint-disable-line
  global.Settings = new SettingsController('.test', true);
} else {
  global.Settings = new SettingsController();
}
Settings.uncouple();

require(`./${process.platform}`);
require('./translations');

document.addEventListener('DOMContentLoaded', () => {
  require('./windowThemeHandler');

  const nativeFrameAtLaunch = Settings.get('nativeFrame');

  document.body.classList.toggle('native-frame', nativeFrameAtLaunch);

  Emitter.on('window:fullscreen', (event, state) => {
    if (nativeFrameAtLaunch) return;
    if (state.state) document.body.classList.add('native-frame');
    if (!state.state) document.body.classList.remove('native-frame');
  });

  document.addEventListener('dragover', (event) => {
    event.preventDefault();
    return false;
  }, false);

  document.addEventListener('drop', (event) => {
    event.preventDefault();
    return false;
  }, false);
});

<|edits_diff|>
--- src/renderer/generic/index.js
+++ src/renderer/generic/index.js
@@ -1,3 +1,4 @@
+import { remote } from 'electron';
 import '../rendererEmitter';
 import './core';

<|current_version|>
import { remote } from 'electron';
import '../rendererEmitter';
import './core';

import SettingsController from '../../main/utils/Settings';

if (process.env['TEST_SPEC']) { // eslint-disable-line
  global.Settings = new SettingsController('.test', true);
} else {
  global.Settings = new SettingsController();
}
Settings.uncouple();

require(`./${process.platform}`);
require('./translations');

document.addEventListener('DOMContentLoaded', () => {
  require('./windowThemeHandler');

  const nativeFrameAtLaunch = Settings.get('nativeFrame');

  document.body.classList.toggle('native-frame', nativeFrameAtLaunch);

  Emitter.on('window:fullscreen', (event, state) => {
    if (nativeFrameAtLaunch) return;
    if (state.state) document.body.classList.add('native-frame');
    if (!state.state) document.body.classList.remove('native-frame');
  });

  document.addEventListener('dragover', (event) => {
    event.preventDefault();
    return false;
  }, false);

  document.addEventListener('drop', (event) => {
    event.preventDefault();
    return false;
  }, false);
});

<|next_version|>
import { remote } from 'electron';
import '../rendererEmitter';
import './core';

import SettingsController from '../../main/utils/Settings';

if (process.env['TEST_SPEC']) { // eslint-disable-line
  global.Settings = new SettingsController('.test', true);
} else {
  global.Settings = new SettingsController();
}
Settings.uncouple();

require(`./${process.platform}`);
require('./translations');

process.env['NODE_ENV'] = remote.getGlobal('DEV_MODE') ? 'development' : 'production';

document.addEventListener('DOMContentLoaded', () => {
  require('./windowThemeHandler');

  const nativeFrameAtLaunch = Settings.get('nativeFrame');

  document.body.classList.toggle('native-frame', nativeFrameAtLaunch);

  Emitter.on('window:fullscreen', (event, state) => {
    if (nativeFrameAtLaunch) return;
    if (state.state) document.body.classList.add('native-frame');
    if (!state.state) document.body.classList.remove('native-frame');
  });

  document.addEventListener('dragover', (event) => {
    event.preventDefault();
    return false;
  }, false);

  document.addEventListener('drop', (event) => {
    event.preventDefault();
    return false;
  }, false);
});


Make map property of ol.MapEvent exportable

--- src/ol/mapevent.js
+++ src/ol/mapevent.js
@@ -37,7 +37,9 @@
   goog.base(this, type);

   /**
+   * The map where the event occurred.
    * @type {ol.Map}
+   * @todo api
    */
   this.map = map;

<|original_code|>
goog.provide('ol.MapEvent');
goog.provide('ol.MapEventType');

goog.require('goog.events.Event');

/**
 * @enum {string}
 */
ol.MapEventType = {
  /**
   * Triggered after a map frame is rendered.
   * @event ol.MapEvent#postrender
   * @todo api
   */
  POSTRENDER: 'postrender',
  /**
   * Triggered after the map is moved.
   * @event ol.MapEvent#moveend
   * @todo api
   */
  MOVEEND: 'moveend'
};

/**
 * @constructor
 * @extends {goog.events.Event}
 * @implements {oli.MapEvent}
 * @param {string} type Event type.
 * @param {ol.Map} map Map.
 * @param {?olx.FrameState=} opt_frameState Frame state.
 */
ol.MapEvent = function(type, map, opt_frameState) {

  goog.base(this, type);

  /**
   * @type {ol.Map}
   */
  this.map = map;

  /**
   * @type {?olx.FrameState}
   */
  this.frameState = goog.isDef(opt_frameState) ? opt_frameState : null;

};
goog.inherits(ol.MapEvent, goog.events.Event);

<|edits_diff|>
--- src/ol/mapevent.js
+++ src/ol/mapevent.js
@@ -37,6 +37,7 @@
   goog.base(this, type);

   /**
+   * The map where the event occurred.
    * @type {ol.Map}
    */
   this.map = map;
<|current_version|>
goog.provide('ol.MapEvent');
goog.provide('ol.MapEventType');

goog.require('goog.events.Event');

/**
 * @enum {string}
 */
ol.MapEventType = {
  /**
   * Triggered after a map frame is rendered.
   * @event ol.MapEvent#postrender
   * @todo api
   */
  POSTRENDER: 'postrender',
  /**
   * Triggered after the map is moved.
   * @event ol.MapEvent#moveend
   * @todo api
   */
  MOVEEND: 'moveend'
};

/**
 * @constructor
 * @extends {goog.events.Event}
 * @implements {oli.MapEvent}
 * @param {string} type Event type.
 * @param {ol.Map} map Map.
 * @param {?olx.FrameState=} opt_frameState Frame state.
 */
ol.MapEvent = function(type, map, opt_frameState) {

  goog.base(this, type);

  /**
   * The map where the event occurred.
   * @type {ol.Map}
   */
  this.map = map;

  /**
   * @type {?olx.FrameState}
   */
  this.frameState = goog.isDef(opt_frameState) ? opt_frameState : null;

};
goog.inherits(ol.MapEvent, goog.events.Event);

<|next_version|>
goog.provide('ol.MapEvent');
goog.provide('ol.MapEventType');

goog.require('goog.events.Event');

/**
 * @enum {string}
 */
ol.MapEventType = {
  /**
   * Triggered after a map frame is rendered.
   * @event ol.MapEvent#postrender
   * @todo api
   */
  POSTRENDER: 'postrender',
  /**
   * Triggered after the map is moved.
   * @event ol.MapEvent#moveend
   * @todo api
   */
  MOVEEND: 'moveend'
};

/**
 * @constructor
 * @extends {goog.events.Event}
 * @implements {oli.MapEvent}
 * @param {string} type Event type.
 * @param {ol.Map} map Map.
 * @param {?olx.FrameState=} opt_frameState Frame state.
 */
ol.MapEvent = function(type, map, opt_frameState) {

  goog.base(this, type);

  /**
   * The map where the event occurred.
   * @type {ol.Map}
   * @todo api
   */
  this.map = map;

  /**
   * @type {?olx.FrameState}
   */
  this.frameState = goog.isDef(opt_frameState) ? opt_frameState : null;

};
goog.inherits(ol.MapEvent, goog.events.Event);


Disable Vue production tip in tests

Disable Vue production tip in tests

--- tests/__setup__.js
+++ tests/__setup__.js
@@ -1,5 +1,8 @@
 import './polyfills/raf'
+import Vue from 'vue'

 global.normalizeHTMLString = function normalizeHTMLString (string) {
   return string.replace(/\n\s*/g, '')
 }
+
+Vue.config.productionTip = false

<|original_code|>
import './polyfills/raf'

global.normalizeHTMLString = function normalizeHTMLString (string) {
  return string.replace(/\n\s*/g, '')
}

<|edits_diff|>
--- tests/__setup__.js
+++ tests/__setup__.js
@@ -1,4 +1,5 @@
 import './polyfills/raf'
+import Vue from 'vue'

 global.normalizeHTMLString = function normalizeHTMLString (string) {
   return string.replace(/\n\s*/g, '')
<|current_version|>
import './polyfills/raf'
import Vue from 'vue'

global.normalizeHTMLString = function normalizeHTMLString (string) {
  return string.replace(/\n\s*/g, '')
}

<|next_version|>
import './polyfills/raf'
import Vue from 'vue'

global.normalizeHTMLString = function normalizeHTMLString (string) {
  return string.replace(/\n\s*/g, '')
}

Vue.config.productionTip = false


FIX a warning in polymer storybook

FIX a warning in polymer storybook

--- examples/polymer-cli/.storybook/webpack.config.js
+++ examples/polymer-cli/.storybook/webpack.config.js
@@ -1,4 +1,5 @@
 const path = require('path');
+const webpack = require('webpack');

 module.exports = (storybookBaseConfig, configType, defaultConfig) => {
   defaultConfig.module.rules.push({
@@ -8,5 +9,8 @@
     enforce: 'pre',
   });

+  // TEMP fix: https://github.com/plotly/plotly.js/issues/2466#issuecomment-372924684
+  defaultConfig.plugins.push(new webpack.IgnorePlugin(/vertx/));
+
   return defaultConfig;
 };

<|original_code|>
const path = require('path');

module.exports = (storybookBaseConfig, configType, defaultConfig) => {
  defaultConfig.module.rules.push({
    test: [/\.stories\.js$/, /index\.js$/],
    loaders: [require.resolve('@storybook/addon-storysource/loader')],
    include: [path.resolve(__dirname, '../src')],
    enforce: 'pre',
  });

  return defaultConfig;
};

<|edits_diff|>
--- examples/polymer-cli/.storybook/webpack.config.js
+++ examples/polymer-cli/.storybook/webpack.config.js
@@ -1,4 +1,5 @@
 const path = require('path');
+const webpack = require('webpack');

 module.exports = (storybookBaseConfig, configType, defaultConfig) => {
   defaultConfig.module.rules.push({
<|current_version|>
const path = require('path');
const webpack = require('webpack');

module.exports = (storybookBaseConfig, configType, defaultConfig) => {
  defaultConfig.module.rules.push({
    test: [/\.stories\.js$/, /index\.js$/],
    loaders: [require.resolve('@storybook/addon-storysource/loader')],
    include: [path.resolve(__dirname, '../src')],
    enforce: 'pre',
  });

  return defaultConfig;
};

<|next_version|>
const path = require('path');
const webpack = require('webpack');

module.exports = (storybookBaseConfig, configType, defaultConfig) => {
  defaultConfig.module.rules.push({
    test: [/\.stories\.js$/, /index\.js$/],
    loaders: [require.resolve('@storybook/addon-storysource/loader')],
    include: [path.resolve(__dirname, '../src')],
    enforce: 'pre',
  });

  // TEMP fix: https://github.com/plotly/plotly.js/issues/2466#issuecomment-372924684
  defaultConfig.plugins.push(new webpack.IgnorePlugin(/vertx/));

  return defaultConfig;
};


--- server/boot/updateModelTime.js
+++ server/boot/updateModelTime.js
@@ -3,21 +3,30 @@
  * Refer to: http://docs.strongloop.com/display/public/LB/Operation+hooks
  * Created by Ting on 2015/5/18.
  */
+var loopback = require('loopback');
 module.exports = function (app) {
   var builtInModels = ['User', 'Email', 'ACL', 'AccessToken', 'Role', 'RoleMapping'];
   app.models().forEach(function (Model) {
     if (builtInModels.indexOf(Model.modelName) == -1) {
       var myModel = app.models[Model.modelName];
       myModel.observe('before save', function updateTimestamp(ctx, next) {
+        var context = loopback.getCurrentContext();
+        var accessToken = context.get('accessToken');
         var now = new Date();
+
         if (ctx.instance) {
+          // Update time of 'created' and 'lastUpdated'.
           ctx.instance.created = now;
           ctx.instance.lastUpdated = now;
+          // Replace 'memberId' according to current accessToken, avoid user change it in client.
+          ctx.instance.memberId = accessToken.userId;
         } else {
           ctx.data.lastUpdated = now;
+          ctx.data.memberId = accessToken.userId;
         }
         next();
       });
     }
   });
 };
+

<|original_code|>
/**
 * For each our own defined models, handle 'created' and 'lastUpdated' automatically.
 * Refer to: http://docs.strongloop.com/display/public/LB/Operation+hooks
 * Created by Ting on 2015/5/18.
 */
module.exports = function (app) {
  var builtInModels = ['User', 'Email', 'ACL', 'AccessToken', 'Role', 'RoleMapping'];
  app.models().forEach(function (Model) {
    if (builtInModels.indexOf(Model.modelName) == -1) {
      var myModel = app.models[Model.modelName];
      myModel.observe('before save', function updateTimestamp(ctx, next) {
        var now = new Date();
        if (ctx.instance) {
          ctx.instance.created = now;
          ctx.instance.lastUpdated = now;
        } else {
          ctx.data.lastUpdated = now;
        }
        next();
      });
    }
  });
};

<|edits_diff|>
--- server/boot/updateModelTime.js
+++ server/boot/updateModelTime.js
@@ -3,18 +3,26 @@
  * Refer to: http://docs.strongloop.com/display/public/LB/Operation+hooks
  * Created by Ting on 2015/5/18.
  */
+var loopback = require('loopback');
 module.exports = function (app) {
   var builtInModels = ['User', 'Email', 'ACL', 'AccessToken', 'Role', 'RoleMapping'];
   app.models().forEach(function (Model) {
     if (builtInModels.indexOf(Model.modelName) == -1) {
       var myModel = app.models[Model.modelName];
       myModel.observe('before save', function updateTimestamp(ctx, next) {
+        var context = loopback.getCurrentContext();
+        var accessToken = context.get('accessToken');
         var now = new Date();
+
         if (ctx.instance) {
+          // Update time of 'created' and 'lastUpdated'.
           ctx.instance.created = now;
           ctx.instance.lastUpdated = now;
+          // Replace 'memberId' according to current accessToken, avoid user change it in client.
+          ctx.instance.memberId = accessToken.userId;
         } else {
           ctx.data.lastUpdated = now;
+          ctx.data.memberId = accessToken.userId;
         }
         next();
       });
<|current_version|>
/**
 * For each our own defined models, handle 'created' and 'lastUpdated' automatically.
 * Refer to: http://docs.strongloop.com/display/public/LB/Operation+hooks
 * Created by Ting on 2015/5/18.
 */
var loopback = require('loopback');
module.exports = function (app) {
  var builtInModels = ['User', 'Email', 'ACL', 'AccessToken', 'Role', 'RoleMapping'];
  app.models().forEach(function (Model) {
    if (builtInModels.indexOf(Model.modelName) == -1) {
      var myModel = app.models[Model.modelName];
      myModel.observe('before save', function updateTimestamp(ctx, next) {
        var context = loopback.getCurrentContext();
        var accessToken = context.get('accessToken');
        var now = new Date();

        if (ctx.instance) {
          // Update time of 'created' and 'lastUpdated'.
          ctx.instance.created = now;
          ctx.instance.lastUpdated = now;
          // Replace 'memberId' according to current accessToken, avoid user change it in client.
          ctx.instance.memberId = accessToken.userId;
        } else {
          ctx.data.lastUpdated = now;
          ctx.data.memberId = accessToken.userId;
        }
        next();
      });
    }
  });
};

<|next_version|>
/**
 * For each our own defined models, handle 'created' and 'lastUpdated' automatically.
 * Refer to: http://docs.strongloop.com/display/public/LB/Operation+hooks
 * Created by Ting on 2015/5/18.
 */
var loopback = require('loopback');
module.exports = function (app) {
  var builtInModels = ['User', 'Email', 'ACL', 'AccessToken', 'Role', 'RoleMapping'];
  app.models().forEach(function (Model) {
    if (builtInModels.indexOf(Model.modelName) == -1) {
      var myModel = app.models[Model.modelName];
      myModel.observe('before save', function updateTimestamp(ctx, next) {
        var context = loopback.getCurrentContext();
        var accessToken = context.get('accessToken');
        var now = new Date();

        if (ctx.instance) {
          // Update time of 'created' and 'lastUpdated'.
          ctx.instance.created = now;
          ctx.instance.lastUpdated = now;
          // Replace 'memberId' according to current accessToken, avoid user change it in client.
          ctx.instance.memberId = accessToken.userId;
        } else {
          ctx.data.lastUpdated = now;
          ctx.data.memberId = accessToken.userId;
        }
        next();
      });
    }
  });
};


Add selector properties to Backbone question view initialization and write function for ajax submission of model

--- app/assets/javascripts/global/views/questions.js
+++ app/assets/javascripts/global/views/questions.js
@@ -13,12 +13,19 @@

   initialize: function(){
     this.initializeTemplates();
+    this.$title = $(".new_question");
+    this.$content = $(".new_content");
+    this.$form = $(".question_form");
+    this.$show = $(".formulated_question")
+    this.model = new app.Question();
   },

   render: function(){},

   submitQuestion: function(e){
     e.preventDefault()
+    this.model.save({title: this.$title.val(), content: this.$content.val()})
+    console.log('geez')
   }

 });

<|original_code|>
app = app || {};

app.QuestionView = Backbone.View.extend({

  events: {
    'submit .question_form': 'submitQuestion',
  },

  initializeTemplates: function(){
    _.templateSettings = { interpolate: /\{\{(.+?)\}\}/g };
    this.template = _.template( $('#question_template').html() )
  },

  initialize: function(){
    this.initializeTemplates();
  },

  render: function(){},

  submitQuestion: function(e){
    e.preventDefault()
  }

});

<|edits_diff|>
--- app/assets/javascripts/global/views/questions.js
+++ app/assets/javascripts/global/views/questions.js
@@ -13,6 +13,11 @@

   initialize: function(){
     this.initializeTemplates();
+    this.$title = $(".new_question");
+    this.$content = $(".new_content");
+    this.$form = $(".question_form");
+    this.$show = $(".formulated_question")
+    this.model = new app.Question();
   },

   render: function(){},
<|current_version|>
app = app || {};

app.QuestionView = Backbone.View.extend({

  events: {
    'submit .question_form': 'submitQuestion',
  },

  initializeTemplates: function(){
    _.templateSettings = { interpolate: /\{\{(.+?)\}\}/g };
    this.template = _.template( $('#question_template').html() )
  },

  initialize: function(){
    this.initializeTemplates();
    this.$title = $(".new_question");
    this.$content = $(".new_content");
    this.$form = $(".question_form");
    this.$show = $(".formulated_question")
    this.model = new app.Question();
  },

  render: function(){},

  submitQuestion: function(e){
    e.preventDefault()
  }

});

<|next_version|>
app = app || {};

app.QuestionView = Backbone.View.extend({

  events: {
    'submit .question_form': 'submitQuestion',
  },

  initializeTemplates: function(){
    _.templateSettings = { interpolate: /\{\{(.+?)\}\}/g };
    this.template = _.template( $('#question_template').html() )
  },

  initialize: function(){
    this.initializeTemplates();
    this.$title = $(".new_question");
    this.$content = $(".new_content");
    this.$form = $(".question_form");
    this.$show = $(".formulated_question")
    this.model = new app.Question();
  },

  render: function(){},

  submitQuestion: function(e){
    e.preventDefault()
    this.model.save({title: this.$title.val(), content: this.$content.val()})
    console.log('geez')
  }

});


Add auto abuse reports after multiple downvotes

--- models/core/AbuseReport.js
+++ models/core/AbuseReport.js
@@ -20,6 +20,9 @@
     // Report text
     text: String,

+    // Flag defining whether this report was created automatically
+    auto_reported: Boolean,
+
     // Parser options
     params_ref: Schema.ObjectId,

@@ -28,6 +31,9 @@
   }, {
     versionKey: false
   });
+
+  // Duplicate check for auto-created abuse reports
+  AbuseReport.index({ src: 1, auto_reported: 1 }, { sparse: true });

   N.wire.on('init:models', function emit_init_AbuseReport() {

<|original_code|>
// Abuse reports
//
'use strict';

const Mongoose = require('mongoose');
const Schema   = Mongoose.Schema;

module.exports = function (N, collectionName) {

  let AbuseReport = new Schema({

    // _id of reported content
    src: Schema.ObjectId,

    // N.shared.content_type (FORUM_POST, BLOG_ENTRY, ...)
    type: Number,

    // Report text
    text: String,

    // Parser options
    params_ref: Schema.ObjectId,

    // User _id
    from: Schema.ObjectId
  }, {
    versionKey: false
  });

  N.wire.on('init:models', function emit_init_AbuseReport() {
    return N.wire.emit('init:models.' + collectionName, AbuseReport);
  });

  N.wire.on('init:models.' + collectionName, function init_model_AbuseReport(schema) {
    N.models[collectionName] = Mongoose.model(collectionName, schema);
  });
};

<|edits_diff|>
--- models/core/AbuseReport.js
+++ models/core/AbuseReport.js
@@ -20,6 +20,9 @@
     // Report text
     text: String,

+    // Flag defining whether this report was created automatically
+    auto_reported: Boolean,
+
     // Parser options
     params_ref: Schema.ObjectId,

<|current_version|>
// Abuse reports
//
'use strict';

const Mongoose = require('mongoose');
const Schema   = Mongoose.Schema;

module.exports = function (N, collectionName) {

  let AbuseReport = new Schema({

    // _id of reported content
    src: Schema.ObjectId,

    // N.shared.content_type (FORUM_POST, BLOG_ENTRY, ...)
    type: Number,

    // Report text
    text: String,

    // Flag defining whether this report was created automatically
    auto_reported: Boolean,

    // Parser options
    params_ref: Schema.ObjectId,

    // User _id
    from: Schema.ObjectId
  }, {
    versionKey: false
  });

  N.wire.on('init:models', function emit_init_AbuseReport() {
    return N.wire.emit('init:models.' + collectionName, AbuseReport);
  });

  N.wire.on('init:models.' + collectionName, function init_model_AbuseReport(schema) {
    N.models[collectionName] = Mongoose.model(collectionName, schema);
  });
};

<|next_version|>
// Abuse reports
//
'use strict';

const Mongoose = require('mongoose');
const Schema   = Mongoose.Schema;

module.exports = function (N, collectionName) {

  let AbuseReport = new Schema({

    // _id of reported content
    src: Schema.ObjectId,

    // N.shared.content_type (FORUM_POST, BLOG_ENTRY, ...)
    type: Number,

    // Report text
    text: String,

    // Flag defining whether this report was created automatically
    auto_reported: Boolean,

    // Parser options
    params_ref: Schema.ObjectId,

    // User _id
    from: Schema.ObjectId
  }, {
    versionKey: false
  });

  // Duplicate check for auto-created abuse reports
  AbuseReport.index({ src: 1, auto_reported: 1 }, { sparse: true });

  N.wire.on('init:models', function emit_init_AbuseReport() {
    return N.wire.emit('init:models.' + collectionName, AbuseReport);
  });

  N.wire.on('init:models.' + collectionName, function init_model_AbuseReport(schema) {
    N.models[collectionName] = Mongoose.model(collectionName, schema);
  });
};