Re-enabled missing tests.

Re-enabled missing tests.

--- test/generators/backbone_rest.coffee
+++ test/generators/backbone_rest.coffee
@@ -67,18 +67,18 @@

     describe 'index', ->

-      # it 'should return json for all models with no query', (done) ->
-      #   app = APP_FACTORY()
-      #   controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-      #   request(app)
-      #     .get(ROUTE)
-      #     .type('json')
-      #     .end (err, res) ->
-      #       assert.ok(!err, "no errors: #{err}")
-      #       assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-      #       assert.deepEqual(expected = MODELS_JSON, actual = sortO(JSONUtils.parse(res.body), 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-      #       done()
+      it 'should return json for all models with no query', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        request(app)
+          .get(ROUTE)
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = MODELS_JSON, actual = sortO(JSONUtils.parse(res.body), 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()

       it 'should select requested keys by single key', (done) ->
         app = APP_FACTORY()
@@ -94,579 +94,579 @@
             assert.deepEqual(expected = _.map(MODELS_JSON, (item) -> _.pick(item, 'name')), actual = sortO(res.body, 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
             done()

-    #   it 'should select requested keys by single key respecting whitelist (key included)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'name', 'created_at']}})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$select: 'name'})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = _.map(MODELS_JSON, (item) -> _.pick(item, 'name')), actual = sortO(res.body, 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested keys by single key respecting whitelist (key excluded)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'created_at', 'updated_at']}})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$select: 'name'})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = _.map(MODELS_JSON, (item) -> []), actual = sortO(res.body, 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested keys by an array of keys', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$select: ['name', 'created_at']})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = _.map(MODELS_JSON, (item) -> _.pick(item, ['name', 'created_at'])), actual = sortO(JSONUtils.parse(res.body), 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested keys by an array of keys respecting whitelist (keys included)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'name', 'created_at', 'updated_at']}})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$select: ['name', 'created_at']})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = _.map(MODELS_JSON, (item) -> _.pick(item, ['name', 'created_at'])), actual = sortO(JSONUtils.parse(res.body), 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested keys by an array of keys respecting whitelist (key excluded)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'created_at', 'updated_at']}})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$select: ['name', 'created_at']})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = sortO(_.map(MODELS_JSON, (item) -> _.pick(item, ['created_at'])), 'created_at'), actual = sortO(JSONUtils.parse(res.body), 'created_at'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested keys by an array of keys respecting whitelist (keys excluded)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'updated_at']}})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$select: ['name', 'created_at']})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = _.map(MODELS_JSON, (item) -> {}), actual = sortO(res.body, 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested values by single key', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$values: 'name'})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> item['name'])), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested values by single key (when a template is present)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, templates: {show: {$select: ['name']}}, default_template: 'show'})
-
-    #     request(app)
-    #     .get(ROUTE)
-    #     .query({$values: 'name'})
-    #     .type('json')
-    #     .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> item['name'])), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested values by single key (in array)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$values: ['name']})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> item['name'])), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested values by single key respecting whitelist (key included)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'name']}})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$values: 'name'})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> item['name'])), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested values by single key respecting whitelist (key excluded)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'created_at']}})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$values: 'name'})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> null)), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested values by an array of keys', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$values: ['name', 'created_at']})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> _.values(_.pick(item, ['name', 'created_at'])))), actual = sortA(JSONUtils.parse(res.body)), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested values by an array of keys respecting whitelist (keys included)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'name', 'created_at']}})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$values: ['name', 'created_at']})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> _.values(_.pick(item, ['name', 'created_at'])))), actual = sortA(JSONUtils.parse(res.body)), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested values by an array of keys respecting whitelist (key excluded)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'name']}})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$values: ['name', 'created_at']})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> _.values(_.pick(item, ['name'])))), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should select requested values by an array of keys respecting whitelist (keys excluded)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'updated_at']}})
-
-    #     request(app)
-    #       .get(ROUTE)
-    #       .query({$values: ['name', 'created_at']})
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> [])), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should trigger pre:index and post:index events on index', (done) ->
-    #     app = APP_FACTORY()
-
-    #     class EventController extends RestController
-    #       constructor: ->
-    #         super(app, {model_type: Flat, route: ROUTE})
-    #     controller = new EventController()
-
-    #     pre_triggered = false
-    #     post_triggered = false
-    #     EventController.on 'pre:index', (req) -> pre_triggered = true if req
-    #     EventController.on 'post:index', (json) -> post_triggered = true if json
-
-    #     request(app)
-    #     .get(ROUTE)
-    #     .type('json')
-    #     .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.ok(pre_triggered, "Pre event trigger: #{pre_triggered}")
-    #         assert.ok(pre_triggered, "Post event trigger: #{post_triggered}")
-    #         done()
-
-    # ######################################
-    # # show
-    # ######################################
-
-    # describe 'show', ->
-    #   it 'should find an existing model', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     request(app)
-    #       .get("#{ROUTE}/#{MODELS_JSON[0].id}")
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = MODELS_JSON[0], actual = JSONUtils.parse(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should find an existing model with whitelist', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {show: ['id', 'name', 'created_at']}})
-
-    #     attributes = _.clone(MODELS_JSON[0])
-    #     request(app)
-    #       .get("#{ROUTE}/#{attributes.id}")
-    #       .type('json')
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(expected = _.pick(attributes, ['id', 'name', 'created_at']), actual = JSONUtils.parse(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
-    #         done()
-
-    #   it 'should trigger pre:show and post:show events on show', (done) ->
-    #     app = APP_FACTORY()
-
-    #     class EventController extends RestController
-    #       constructor: ->
-    #         super(app, {model_type: Flat, route: ROUTE})
-    #     controller = new EventController()
-
-    #     pre_triggered = false
-    #     post_triggered = false
-    #     EventController.on 'pre:show', (req) -> pre_triggered = true if req
-    #     EventController.on 'post:show', (json) -> post_triggered = true if json
-
-    #     request(app)
-    #     .get("#{ROUTE}/#{MODELS_JSON[0].id}")
-    #     .type('json')
-    #     .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.ok(pre_triggered, "Pre event trigger: #{pre_triggered}")
-    #         assert.ok(pre_triggered, "Post event trigger: #{post_triggered}")
-    #         done()
-
-    # ######################################
-    # # create
-    # ######################################
-
-    # describe 'create', ->
-    #   it 'should create a new model and assign an id', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     attributes = {name: _.uniqueId('name_'), created_at: (new Date).toISOString(), updated_at: (new Date).toISOString()}
-    #     request(app)
-    #       .post(ROUTE)
-    #       .send(attributes)
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.ok(!!res.body.id, 'assigned an id')
-    #         assert.equal(attributes.name, res.body.name, 'name matches')
-    #         done()
-
-    #   it 'should create a new model and assign an id with whitelist', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {create: ['id', 'name', 'updated_at']}})
-
-    #     attributes = {name: _.uniqueId('name_'), created_at: (new Date).toISOString(), updated_at: (new Date).toISOString()}
-    #     request(app)
-    #       .post(ROUTE)
-    #       .send(attributes)
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.ok(!!res.body.id, 'assigned an id')
-    #         assert.equal(attributes.name, res.body.name, 'name matches')
-    #         assert.equal(attributes.updated_at, res.body.updated_at, 'updated_at matches')
-    #         assert.ok(!res.body.created_at, 'created_at was not returned')
-    #         done()
-
-    #   it 'should trigger pre:create and post:create events on create', (done) ->
-    #     app = APP_FACTORY()
-
-    #     class EventController extends RestController
-    #       constructor: ->
-    #         super(app, {model_type: Flat, route: ROUTE})
-    #     controller = new EventController()
-
-    #     pre_triggered = false
-    #     post_triggered = false
-    #     EventController.on 'pre:create', (req) -> pre_triggered = true if req
-    #     EventController.on 'post:create', (json) -> post_triggered = true if json
-
-    #     attributes = {name: _.uniqueId('name_'), created_at: (new Date).toISOString(), updated_at: (new Date).toISOString()}
-    #     request(app)
-    #     .post(ROUTE)
-    #     .send(attributes)
-    #     .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.ok(pre_triggered, "Pre event trigger: #{pre_triggered}")
-    #         assert.ok(pre_triggered, "Post event trigger: #{post_triggered}")
-    #         done()
-
-    # ######################################
-    # # update
-    # ######################################
-
-    # describe 'update', ->
-    #   it 'should update an existing model', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     attributes = _.clone(MODELS_JSON[1])
-    #     attributes.name = "#{attributes.name}_#{_.uniqueId('name')}"
-    #     request(app)
-    #       .put("#{ROUTE}/#{attributes.id}")
-    #       .send(attributes)
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(_.omit(attributes, '_rev'), _.omit(JSONUtils.parse(res.body), '_rev'), 'model was updated') # there could be _rev added
-    #         done()
-
-    #   it 'should update an existing model with whitelist', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {update: ['id', 'name', 'updated_at']}})
-
-    #     attributes = _.clone(MODELS_JSON[1])
-    #     attributes.name = "#{attributes.name}_#{_.uniqueId('name')}"
-    #     request(app)
-    #       .put("#{ROUTE}/#{attributes.id}")
-    #       .send(attributes)
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.deepEqual(_.pick(attributes, ['id', 'name', 'updated_at']), JSONUtils.parse(res.body), 'model was updated')
-    #         done()
-
-    #   it 'should trigger pre:update and post:create events on update', (done) ->
-    #     app = APP_FACTORY()
-
-    #     class EventController extends RestController
-    #       constructor: ->
-    #         super(app, {model_type: Flat, route: ROUTE})
-    #     controller = new EventController()
-
-    #     pre_triggered = false
-    #     post_triggered = false
-    #     EventController.on 'pre:update', (req) -> pre_triggered = true if req
-    #     EventController.on 'post:update', (json) -> post_triggered = true if json
-
-    #     attributes = _.clone(MODELS_JSON[1])
-    #     attributes.name = "#{attributes.name}_#{_.uniqueId('name')}"
-    #     request(app)
-    #     .put("#{ROUTE}/#{attributes.id}")
-    #     .send(attributes)
-    #     .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.ok(pre_triggered, "Pre event trigger: #{pre_triggered}")
-    #         assert.ok(pre_triggered, "Post event trigger: #{post_triggered}")
-    #         done()
-
-    # ######################################
-    # # delete
-    # ######################################
-
-    # describe 'delete', ->
-    #   it 'should delete an existing model', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     id = MODELS_JSON[1].id
-    #     request(app)
-    #       .del("#{ROUTE}/#{id}")
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-
-    #         request(app)
-    #           .get("#{ROUTE}/#{id}")
-    #           .end (err, res) ->
-    #             assert.ok(!err, "no errors: #{err}")
-    #             assert.equal(res.status, 404, "status 404 on subsequent request. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #             done()
-
-    #   it 'should trigger pre:destroy and post:destroy events on destroy', (done) ->
-    #     app = APP_FACTORY()
-
-    #     class EventController extends RestController
-    #       constructor: ->
-    #         super(app, {model_type: Flat, route: ROUTE})
-    #     controller = new EventController()
-
-    #     pre_triggered = false
-    #     post_triggered = false
-    #     EventController.on 'pre:destroy', (req) -> pre_triggered = true if req
-    #     EventController.on 'post:destroy', (json) -> post_triggered = true if json
-
-    #     id = MODELS_JSON[1].id
-    #     request(app)
-    #     .del("#{ROUTE}/#{id}")
-    #     .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.ok(pre_triggered, "Pre event trigger: #{pre_triggered}")
-    #         assert.ok(pre_triggered, "Post event trigger: #{post_triggered}")
-    #         done()
-
-    # ######################################
-    # # head
-    # ######################################
-
-    # describe 'head', ->
-    #   it 'should test existence of a model by id', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     id = MODELS_JSON[1].id
-    #     request(app)
-    #       .head("#{ROUTE}/#{id}")
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-
-    #         # delete it
-    #         request(app)
-    #           .del("#{ROUTE}/#{id}")
-    #           .end (err, res) ->
-    #             assert.ok(!err, "no errors: #{err}")
-    #             assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-
-    #             # check again
-    #             request(app)
-    #               .head("#{ROUTE}/#{id}")
-    #               .end (err, res) ->
-    #                 assert.ok(!err, "no errors: #{err}")
-    #                 assert.equal(res.status, 404, "status not 404. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #                 done()
-
-    #   it 'should test existence of a model by id ($exists)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     id = MODELS_JSON[1].id
-    #     request(app)
-    #       .get("#{ROUTE}")
-    #       .query({id: id, $exists: ''})
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.ok(res.body.result, "Exists by id. Body: #{util.inspect(res.body)}")
-
-    #         # delete it
-    #         request(app)
-    #           .del("#{ROUTE}/#{id}")
-    #           .end (err, res) ->
-    #             assert.ok(!err, "no errors: #{err}")
-    #             assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-
-    #             # check again
-    #             request(app)
-    #               .get("#{ROUTE}")
-    #               .query({id: id, $exists: ''})
-    #               .end (err, res) ->
-    #                 assert.ok(!err, "no errors: #{err}")
-    #                 assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #                 assert.ok(!res.body.result, "Not longer exists by id. Body: #{util.inspect(res.body)}")
-    #                 done()
-
-    #   it 'should test existence of a model by name', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     id = MODELS_JSON[1].id
-    #     name = MODELS_JSON[1].name
-    #     request(app)
-    #       .head("#{ROUTE}")
-    #       .query({name: name})
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-
-    #         # delete it
-    #         request(app)
-    #           .del("#{ROUTE}/#{id}")
-    #           .end (err, res) ->
-    #             assert.ok(!err, "no errors: #{err}")
-    #             assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-
-    #             # check again
-    #             request(app)
-    #               .head("#{ROUTE}")
-    #               .query({name: name})
-    #               .end (err, res) ->
-    #                 assert.ok(!err, "no errors: #{err}")
-    #                 assert.equal(res.status, 404, "status not 404. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #                 done()
-
-    #   it 'should test existence of a model by name ($exists)', (done) ->
-    #     app = APP_FACTORY()
-    #     controller = new RestController(app, {model_type: Flat, route: ROUTE})
-
-    #     id = MODELS_JSON[1].id
-    #     name = MODELS_JSON[1].name
-    #     request(app)
-    #       .get("#{ROUTE}")
-    #       .query({name: name, $exists: ''})
-    #       .end (err, res) ->
-    #         assert.ok(!err, "no errors: #{err}")
-    #         assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #         assert.ok(res.body.result, "Exists by name. Body: #{util.inspect(res.body)}")
-
-    #         # delete it
-    #         request(app)
-    #           .del("#{ROUTE}/#{id}")
-    #           .end (err, res) ->
-    #             assert.ok(!err, "no errors: #{err}")
-    #             assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-
-    #             # check again
-    #             request(app)
-    #               .get("#{ROUTE}")
-    #               .query({name: name, $exists: ''})
-    #               .end (err, res) ->
-    #                 assert.ok(!err, "no errors: #{err}")
-    #                 assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
-    #                 assert.ok(!res.body.result, "No longer exists by name. Body: #{util.inspect(res.body)}")
-    #                 done()
-
+      it 'should select requested keys by single key respecting whitelist (key included)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'name', 'created_at']}})
+
+        request(app)
+          .get(ROUTE)
+          .query({$select: 'name'})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = _.map(MODELS_JSON, (item) -> _.pick(item, 'name')), actual = sortO(res.body, 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested keys by single key respecting whitelist (key excluded)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'created_at', 'updated_at']}})
+
+        request(app)
+          .get(ROUTE)
+          .query({$select: 'name'})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = _.map(MODELS_JSON, (item) -> []), actual = sortO(res.body, 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested keys by an array of keys', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        request(app)
+          .get(ROUTE)
+          .query({$select: ['name', 'created_at']})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = _.map(MODELS_JSON, (item) -> _.pick(item, ['name', 'created_at'])), actual = sortO(JSONUtils.parse(res.body), 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested keys by an array of keys respecting whitelist (keys included)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'name', 'created_at', 'updated_at']}})
+
+        request(app)
+          .get(ROUTE)
+          .query({$select: ['name', 'created_at']})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = _.map(MODELS_JSON, (item) -> _.pick(item, ['name', 'created_at'])), actual = sortO(JSONUtils.parse(res.body), 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested keys by an array of keys respecting whitelist (key excluded)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'created_at', 'updated_at']}})
+
+        request(app)
+          .get(ROUTE)
+          .query({$select: ['name', 'created_at']})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = sortO(_.map(MODELS_JSON, (item) -> _.pick(item, ['created_at'])), 'created_at'), actual = sortO(JSONUtils.parse(res.body), 'created_at'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested keys by an array of keys respecting whitelist (keys excluded)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'updated_at']}})
+
+        request(app)
+          .get(ROUTE)
+          .query({$select: ['name', 'created_at']})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = _.map(MODELS_JSON, (item) -> {}), actual = sortO(res.body, 'name'), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested values by single key', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        request(app)
+          .get(ROUTE)
+          .query({$values: 'name'})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> item['name'])), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested values by single key (when a template is present)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, templates: {show: {$select: ['name']}}, default_template: 'show'})
+
+        request(app)
+        .get(ROUTE)
+        .query({$values: 'name'})
+        .type('json')
+        .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> item['name'])), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested values by single key (in array)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        request(app)
+          .get(ROUTE)
+          .query({$values: ['name']})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> item['name'])), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested values by single key respecting whitelist (key included)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'name']}})
+
+        request(app)
+          .get(ROUTE)
+          .query({$values: 'name'})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> item['name'])), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested values by single key respecting whitelist (key excluded)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'created_at']}})
+
+        request(app)
+          .get(ROUTE)
+          .query({$values: 'name'})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> null)), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested values by an array of keys', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        request(app)
+          .get(ROUTE)
+          .query({$values: ['name', 'created_at']})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> _.values(_.pick(item, ['name', 'created_at'])))), actual = sortA(JSONUtils.parse(res.body)), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested values by an array of keys respecting whitelist (keys included)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'name', 'created_at']}})
+
+        request(app)
+          .get(ROUTE)
+          .query({$values: ['name', 'created_at']})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> _.values(_.pick(item, ['name', 'created_at'])))), actual = sortA(JSONUtils.parse(res.body)), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested values by an array of keys respecting whitelist (key excluded)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'name']}})
+
+        request(app)
+          .get(ROUTE)
+          .query({$values: ['name', 'created_at']})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> _.values(_.pick(item, ['name'])))), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should select requested values by an array of keys respecting whitelist (keys excluded)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {index: ['id', 'updated_at']}})
+
+        request(app)
+          .get(ROUTE)
+          .query({$values: ['name', 'created_at']})
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = sortA(_.map(MODELS_JSON, (item) -> [])), actual = sortA(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should trigger pre:index and post:index events on index', (done) ->
+        app = APP_FACTORY()
+
+        class EventController extends RestController
+          constructor: ->
+            super(app, {model_type: Flat, route: ROUTE})
+        controller = new EventController()
+
+        pre_triggered = false
+        post_triggered = false
+        EventController.on 'pre:index', (req) -> pre_triggered = true if req
+        EventController.on 'post:index', (json) -> post_triggered = true if json
+
+        request(app)
+        .get(ROUTE)
+        .type('json')
+        .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.ok(pre_triggered, "Pre event trigger: #{pre_triggered}")
+            assert.ok(pre_triggered, "Post event trigger: #{post_triggered}")
+            done()
+
+    ######################################
+    # show
+    ######################################
+
+    describe 'show', ->
+      it 'should find an existing model', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        request(app)
+          .get("#{ROUTE}/#{MODELS_JSON[0].id}")
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = MODELS_JSON[0], actual = JSONUtils.parse(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should find an existing model with whitelist', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {show: ['id', 'name', 'created_at']}})
+
+        attributes = _.clone(MODELS_JSON[0])
+        request(app)
+          .get("#{ROUTE}/#{attributes.id}")
+          .type('json')
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(expected = _.pick(attributes, ['id', 'name', 'created_at']), actual = JSONUtils.parse(res.body), "Expected: #{util.inspect(expected)}. Actual: #{util.inspect(actual)}")
+            done()
+
+      it 'should trigger pre:show and post:show events on show', (done) ->
+        app = APP_FACTORY()
+
+        class EventController extends RestController
+          constructor: ->
+            super(app, {model_type: Flat, route: ROUTE})
+        controller = new EventController()
+
+        pre_triggered = false
+        post_triggered = false
+        EventController.on 'pre:show', (req) -> pre_triggered = true if req
+        EventController.on 'post:show', (json) -> post_triggered = true if json
+
+        request(app)
+        .get("#{ROUTE}/#{MODELS_JSON[0].id}")
+        .type('json')
+        .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.ok(pre_triggered, "Pre event trigger: #{pre_triggered}")
+            assert.ok(pre_triggered, "Post event trigger: #{post_triggered}")
+            done()
+
+    ######################################
+    # create
+    ######################################
+
+    describe 'create', ->
+      it 'should create a new model and assign an id', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        attributes = {name: _.uniqueId('name_'), created_at: (new Date).toISOString(), updated_at: (new Date).toISOString()}
+        request(app)
+          .post(ROUTE)
+          .send(attributes)
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.ok(!!res.body.id, 'assigned an id')
+            assert.equal(attributes.name, res.body.name, 'name matches')
+            done()
+
+      it 'should create a new model and assign an id with whitelist', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {create: ['id', 'name', 'updated_at']}})
+
+        attributes = {name: _.uniqueId('name_'), created_at: (new Date).toISOString(), updated_at: (new Date).toISOString()}
+        request(app)
+          .post(ROUTE)
+          .send(attributes)
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.ok(!!res.body.id, 'assigned an id')
+            assert.equal(attributes.name, res.body.name, 'name matches')
+            assert.equal(attributes.updated_at, res.body.updated_at, 'updated_at matches')
+            assert.ok(!res.body.created_at, 'created_at was not returned')
+            done()
+
+      it 'should trigger pre:create and post:create events on create', (done) ->
+        app = APP_FACTORY()
+
+        class EventController extends RestController
+          constructor: ->
+            super(app, {model_type: Flat, route: ROUTE})
+        controller = new EventController()
+
+        pre_triggered = false
+        post_triggered = false
+        EventController.on 'pre:create', (req) -> pre_triggered = true if req
+        EventController.on 'post:create', (json) -> post_triggered = true if json
+
+        attributes = {name: _.uniqueId('name_'), created_at: (new Date).toISOString(), updated_at: (new Date).toISOString()}
+        request(app)
+        .post(ROUTE)
+        .send(attributes)
+        .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.ok(pre_triggered, "Pre event trigger: #{pre_triggered}")
+            assert.ok(pre_triggered, "Post event trigger: #{post_triggered}")
+            done()
+
+    ######################################
+    # update
+    ######################################
+
+    describe 'update', ->
+      it 'should update an existing model', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        attributes = _.clone(MODELS_JSON[1])
+        attributes.name = "#{attributes.name}_#{_.uniqueId('name')}"
+        request(app)
+          .put("#{ROUTE}/#{attributes.id}")
+          .send(attributes)
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(_.omit(attributes, '_rev'), _.omit(JSONUtils.parse(res.body), '_rev'), 'model was updated') # there could be _rev added
+            done()
+
+      it 'should update an existing model with whitelist', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE, white_lists: {update: ['id', 'name', 'updated_at']}})
+
+        attributes = _.clone(MODELS_JSON[1])
+        attributes.name = "#{attributes.name}_#{_.uniqueId('name')}"
+        request(app)
+          .put("#{ROUTE}/#{attributes.id}")
+          .send(attributes)
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.deepEqual(_.pick(attributes, ['id', 'name', 'updated_at']), JSONUtils.parse(res.body), 'model was updated')
+            done()
+
+      it 'should trigger pre:update and post:create events on update', (done) ->
+        app = APP_FACTORY()
+
+        class EventController extends RestController
+          constructor: ->
+            super(app, {model_type: Flat, route: ROUTE})
+        controller = new EventController()
+
+        pre_triggered = false
+        post_triggered = false
+        EventController.on 'pre:update', (req) -> pre_triggered = true if req
+        EventController.on 'post:update', (json) -> post_triggered = true if json
+
+        attributes = _.clone(MODELS_JSON[1])
+        attributes.name = "#{attributes.name}_#{_.uniqueId('name')}"
+        request(app)
+        .put("#{ROUTE}/#{attributes.id}")
+        .send(attributes)
+        .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.ok(pre_triggered, "Pre event trigger: #{pre_triggered}")
+            assert.ok(pre_triggered, "Post event trigger: #{post_triggered}")
+            done()
+
+    ######################################
+    # delete
+    ######################################
+
+    describe 'delete', ->
+      it 'should delete an existing model', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        id = MODELS_JSON[1].id
+        request(app)
+          .del("#{ROUTE}/#{id}")
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+
+            request(app)
+              .get("#{ROUTE}/#{id}")
+              .end (err, res) ->
+                assert.ok(!err, "no errors: #{err}")
+                assert.equal(res.status, 404, "status 404 on subsequent request. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+                done()
+
+      it 'should trigger pre:destroy and post:destroy events on destroy', (done) ->
+        app = APP_FACTORY()
+
+        class EventController extends RestController
+          constructor: ->
+            super(app, {model_type: Flat, route: ROUTE})
+        controller = new EventController()
+
+        pre_triggered = false
+        post_triggered = false
+        EventController.on 'pre:destroy', (req) -> pre_triggered = true if req
+        EventController.on 'post:destroy', (json) -> post_triggered = true if json
+
+        id = MODELS_JSON[1].id
+        request(app)
+        .del("#{ROUTE}/#{id}")
+        .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.ok(pre_triggered, "Pre event trigger: #{pre_triggered}")
+            assert.ok(pre_triggered, "Post event trigger: #{post_triggered}")
+            done()
+
+    ######################################
+    # head
+    ######################################
+
+    describe 'head', ->
+      it 'should test existence of a model by id', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        id = MODELS_JSON[1].id
+        request(app)
+          .head("#{ROUTE}/#{id}")
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+
+            # delete it
+            request(app)
+              .del("#{ROUTE}/#{id}")
+              .end (err, res) ->
+                assert.ok(!err, "no errors: #{err}")
+                assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+
+                # check again
+                request(app)
+                  .head("#{ROUTE}/#{id}")
+                  .end (err, res) ->
+                    assert.ok(!err, "no errors: #{err}")
+                    assert.equal(res.status, 404, "status not 404. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+                    done()
+
+      it 'should test existence of a model by id ($exists)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        id = MODELS_JSON[1].id
+        request(app)
+          .get("#{ROUTE}")
+          .query({id: id, $exists: ''})
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.ok(res.body.result, "Exists by id. Body: #{util.inspect(res.body)}")
+
+            # delete it
+            request(app)
+              .del("#{ROUTE}/#{id}")
+              .end (err, res) ->
+                assert.ok(!err, "no errors: #{err}")
+                assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+
+                # check again
+                request(app)
+                  .get("#{ROUTE}")
+                  .query({id: id, $exists: ''})
+                  .end (err, res) ->
+                    assert.ok(!err, "no errors: #{err}")
+                    assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+                    assert.ok(!res.body.result, "Not longer exists by id. Body: #{util.inspect(res.body)}")
+                    done()
+
+      it 'should test existence of a model by name', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        id = MODELS_JSON[1].id
+        name = MODELS_JSON[1].name
+        request(app)
+          .head("#{ROUTE}")
+          .query({name: name})
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+
+            # delete it
+            request(app)
+              .del("#{ROUTE}/#{id}")
+              .end (err, res) ->
+                assert.ok(!err, "no errors: #{err}")
+                assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+
+                # check again
+                request(app)
+                  .head("#{ROUTE}")
+                  .query({name: name})
+                  .end (err, res) ->
+                    assert.ok(!err, "no errors: #{err}")
+                    assert.equal(res.status, 404, "status not 404. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+                    done()
+
+      it 'should test existence of a model by name ($exists)', (done) ->
+        app = APP_FACTORY()
+        controller = new RestController(app, {model_type: Flat, route: ROUTE})
+
+        id = MODELS_JSON[1].id
+        name = MODELS_JSON[1].name
+        request(app)
+          .get("#{ROUTE}")
+          .query({name: name, $exists: ''})
+          .end (err, res) ->
+            assert.ok(!err, "no errors: #{err}")
+            assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+            assert.ok(res.body.result, "Exists by name. Body: #{util.inspect(res.body)}")
+
+            # delete it
+            request(app)
+              .del("#{ROUTE}/#{id}")
+              .end (err, res) ->
+                assert.ok(!err, "no errors: #{err}")
+                assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+
+                # check again
+                request(app)
+                  .get("#{ROUTE}")
+                  .query({name: name, $exists: ''})
+                  .end (err, res) ->
+                    assert.ok(!err, "no errors: #{err}")
+                    assert.equal(res.status, 200, "status not 200. Status: #{res.status}. Body: #{util.inspect(res.body)}")
+                    assert.ok(!res.body.result, "No longer exists by name. Body: #{util.inspect(res.body)}")
+                    done()
+


Updated the testing tasks for consistency.

--- app/templates/_Gruntfile.coffee
+++ app/templates/_Gruntfile.coffee
@@ -19,7 +19,7 @@
     env:
       default:
         LIB_FOR_TESTS_DIR: srcLibForTestsDir
-      mochaTest:
+      test:
         NODE_ENV: 'testing'
       coverage:
         LIB_FOR_TESTS_DIR: lcovLibForTestsDir
@@ -43,7 +43,7 @@

     watch:
       files: ['Gruntfile.coffee', 'test/**/*.js', 'lib/**/*.js']
-      tasks: ['jshint','mochaTest']
+      tasks: ['cover']

     instrument:
       files: './lib/**/*.js'
@@ -81,18 +81,19 @@
   grunt.loadNpmTasks('grunt-istanbul-coverage')
   grunt.loadNpmTasks('grunt-notify')

-  grunt.registerTask 'test', ['jshint', 'mochaTest']
-  grunt.registerTask 'default', ['test']
+  grunt.registerTask 'test', ['env:test', 'jshint', 'mochaTest']

   grunt.registerTask 'cover', [
     'clean:coverage',
     'env:coverage',
     'instrument',
-    'mochaTest',
+    'test',
     'storeCoverage',
     'makeReport',
     'coverage'
   ]
+
+  grunt.registerTask 'default', ['cover']

 #  grunt.registerMultiTask 'coverme', 'istanbul code coverage', () ->
 #    done = this.async()


Remove debug

Remove debug

--- app/src/wallet/derivation_worker.coffee
+++ app/src/wallet/derivation_worker.coffee
@@ -91,11 +91,6 @@
     return
   sendCommand 'private:getXpubFromCache', [path], (xpu58, error) =>
     ExtendedPublicKeys[path] = new ledger.wallet.ExtendedPublicKey(ledger.app.dongle, path)
-    xpu58 = {
-      "44'/0'/0'": "xpub6BgT3ekbq7uzzScQZ11TRCiXY7jemvxZQNYijeH5vCoUqR8BpZou6PV7KFaN6Gj6NLEBHdz4YiwcT8zgwsCTcN2Usf4gybrHPZXStBEsqgu"
-      "44'/0'/1'": "xpub6BgT3ekbq7v131Ha5eyrj984qEBvkAUx1onF9tr9oxYc1bVCDkW1ic5F168rYbhQ3hmeG4Hf2uPxUd7ULBEjRPnc95puMsLwuLhmTjbAjA5"
-      "44'/0'/2'": "xpub6D4waFVPfPCpZtpCLcfWBKLy2BqmWxDGuYVn4DmHyDSeVUDzjD5AsHy98SDmyXoiKmLWpsdfZszbcveZzFaEY6NhZSqw476xXu8LYBosvbG"
-    }[path]
     if xpu58?
       ExtendedPublicKeys[path].initializeWithBase58(xpu58)
       postResult 'registered'


cannon prefix

cannon prefix

--- lib/Cycler.coffee
+++ lib/Cycler.coffee
@@ -7,8 +7,8 @@
   constructor: ({@source, @prefix}) ->
     #@source ?= ['localhost']
     if @source?
-      exec "ifconfig cannon 0.0.0.0"
-      exec "ifconfig cannon:#{idx} #{ip}" for ip, idx in @source
+      exec "ifconfig eth0 0.0.0.0"
+      exec "ifconfig eth0:#{idx} #{ip} netmask 255.255.255.248 up" for ip, idx in @source[0..50]
     @range = 8 - @prefix.split(':').length if @prefix?

   # TODO: Support for ipv4 ranges


Tiny fix for gulp-babel config.

Tiny fix for gulp-babel config.

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -167,7 +167,12 @@
       .pipe source "common.js"
       .pipe do vinylBuffer
       .pipe if isDevel then do gutil.noop else envify NODE_ENV: "production"
-      .pipe if isDevel then do gutil.noop else babel presets: ["babili"]
+      .pipe (
+        if isDevel
+          do gutil.noop
+        else
+          babel presets: ["babili"], comments: no
+      )
       .pipe gulp.dest COFFEE_DEST

   do rebuildBundle # Just rebuild bundle before run watcher


Remove dead code from wheel_zoom_tool

Remove dead code from wheel_zoom_tool

--- bokehjs/src/coffee/models/tools/gestures/wheel_zoom_tool.coffee
+++ bokehjs/src/coffee/models/tools/gestures/wheel_zoom_tool.coffee
@@ -25,12 +25,6 @@

     vx = @plot_view.canvas.sx_to_vx(e.bokeh.sx)
     vy = @plot_view.canvas.sy_to_vy(e.bokeh.sy)
-
-    # if wheel-scroll events happen outside frame restrict scaling to axis in bounds
-    if vx < hr.start or vx > hr.end
-      v_axis_only = true
-    if vy < vr.start or vy > vr.end
-      h_axis_only = true

     dims = @model.dimensions


gulpモジュール変更 "gulp-webpack" → "wabpack-stream"

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -1,5 +1,5 @@
 gulp = require 'gulp'
-webpack = require 'gulp-webpack'
+webpack = require 'webpack-stream'
 ts = require 'gulp-typescript'
 tsc = require 'typescript'
 typedoc = require 'gulp-typedoc'


No longer make webpack:tests dependant on webpack:debug

We handle that in the Makefile now

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -91,7 +91,7 @@

 	webpackDev("webpack:release", config, callback)

-gulp.task "webpack:tests", ["webpack:debug"], (callback) ->
+gulp.task "webpack:tests", (callback) ->

 	config = _.extend WEBPACK,
 		entry: "./test/tests.coffee"


gulp tasks for phonegap builds

gulp tasks for phonegap builds

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -97,12 +97,12 @@
 	gulp.src MAIN_SCRIPT
 		.pipe open '', url: "http://localhost:#{EXPRESS_PORT}/"

-gulp.task 'run-android', ['build'], ->
-	gulp.src MAIN_SCRIPT
-		.pipe exec 'pushd phonegap-build && phonegap run android && popd'
+phonegapCommand = (cmd) ->
+	exec "pushd phonegap-build && phonegap #{cmd} && popd"

-gulp.task 'run-ios', ['build'], ->
-	gulp.src MAIN_SCRIPT
-		.pipe exec 'pushd phonegap-build && phonegap run ios && popd'
+gulp.task 'build-android', ['build'], -> gulp.src(MAIN_SCRIPT).pipe phonegapCommand 'build android'
+gulp.task 'run-android', ['build'], -> gulp.src(MAIN_SCRIPT).pipe phonegapCommand 'run android'
+gulp.task 'build-ios', ['build'], -> gulp.src(MAIN_SCRIPT).pipe phonegapCommand 'build ios'
+gulp.task 'run-ios', ['build'], -> gulp.src(MAIN_SCRIPT).pipe phonegapCommand 'run ios'

 gulp.task 'default', ['build']


Enabled pretty html output

Enabled pretty html output

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -26,7 +26,8 @@

 gulp.task 'jade', ->
 	gulp.src 'jade/*.jade'
-		.pipe do jade
+		.pipe jade
+			pretty: yes
 		.pipe gulp.dest 'dist'
 		.pipe do connect.reload


Did more shit

Did more shit

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -122,13 +122,12 @@

     status = git 'status'
     if status.indexOf( 'nothing to commit, working directory clean' ) isnt -1
-        console.log 'Nothing to commit!'
-        return
-
-    # console.log 'Committing source'
-    git 'add .'
-    git "commit -m \"#{args.m || args.msg}\""
-    git 'push'
+        console.log 'Nothing to commit from source'
+    else
+        console.log 'Committing source'
+        git 'add .'
+        git "commit -m \"#{args.m || args.msg}\""
+        git 'push'

     console.log 'Cleaning compiled site'
     if fs.existsSync 'site'
@@ -136,7 +135,7 @@
     fs.mkdirSync 'site'
     cd 'site'

-    # console.log 'Initializing site repo'
+    console.log 'Initializing site repo'
     git "clone -b #{projectConfig.repo.branch.site} #{url} ."

     console.log 'Compiling site'
@@ -157,7 +156,7 @@
         git "commit -m \"#{args.m || args.msg}\""
         git 'push -f'
     else
-        console.log 'Nothing to commit for site!'
+        console.log 'Nothing to commit from site'

     console.log 'Commit done!'


remove unnecessary requires from gulpfile

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -10,13 +10,10 @@
 streamify  = require 'gulp-streamify'
 rename     = require 'gulp-rename'
 uglify     = require 'gulp-uglify'
-coffeeify  = require 'coffeeify'
 ecstatic   = require 'ecstatic'
 livereload = require 'gulp-livereload'
 plumber    = require 'gulp-plumber'
 prefix     = require 'gulp-autoprefixer'
-debowerify = require 'debowerify'
-deamdify   = require 'deamdify'

 production = process.env.NODE_ENV is 'production'


Easier syntax

Easier syntax

--- core/app/backbone/views/evidence/evidence_container_view.coffee
+++ core/app/backbone/views/evidence/evidence_container_view.coffee
@@ -29,7 +29,7 @@
       @_addEvidenceFormView = new AddEvidenceFormView collection: @collection
       @formRegion.show @_addEvidenceFormView

-    if !Factlink.Global.signed_in
+    else
       @opinionHelpRegion.show new OpinionHelpView collection: @collection

     @collectionRegion.show new EvidenceCollectionView collection: @collection


removed sourcemaps that made this thing take 6 seconds just to generate css. Crazy.

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -23,10 +23,8 @@
 gulp.task 'less:compile', ['bower'], ->
   gulp.src [ 'less/manifest.less' ]
       .pipe plumber()
-      .pipe sourcemaps.init()
       .pipe less()
-      .pipe concat('styles.css')
-      .pipe sourcemaps.write('.')
+      .pipe concat('styles.css')
       .pipe gulp.dest('./public/assets/dist/')

 gulp.task 'coffee:compile', ->


Update gulpfile according to the update of gulp-chmod.

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -20,7 +20,7 @@
 gulp.task "bin", ["clean"], ->
   gulp.src "./src/cli.coffee"
     .pipe coffee()
-    .pipe chmod 755
+    .pipe chmod 0o755
     .pipe inject.prepend "#!/usr/bin/env node\n"
     .pipe gulp.dest "./bin/"


Make the request for gold standard data

Make the request for gold standard data

--- app/classifier/index.cjsx
+++ app/classifier/index.cjsx
@@ -68,22 +68,17 @@

   getExpertClassification: (workflow, subject) ->
     awaitExpertClassification = Promise.resolve do =>
-      if subject is mockData?.subject
-        subject.expert_classification_data
-      else
-        # TODO!
-        # apiClient.type('classifications').get({
-        #   gold_standard: true
-        #   workflow_id: workflow.id
-        #   subject_ids: [subject.id]
-        # })
-        #   .catch ->
-        #     []
-        #   .then ([expertClassification]) ->
-        #     expertClassification
-        null
+      apiClient.get('/classifications/gold_standard', {
+        workflow_id: workflow.id,
+        subject_ids: [subject.id]
+      })
+        .catch ->
+          []
+        .then ([expertClassification]) ->
+          expertClassification

     awaitExpertClassification.then (expertClassification) =>
+      expertClassification ?= subject.expert_classification_data?[workflow.id]
       if @props.workflow is workflow and @props.subject is subject
         window.expertClassification = expertClassification
         @setState {expertClassification}


Added netban event

Added netban event

--- app/lib/binds/bind.coffee
+++ app/lib/binds/bind.coffee
@@ -12,6 +12,7 @@
       'capture'
       'flaggrab'
       'flagreturn'
+      'netban'
     ]

     @teeworlds = null


Update hour of code year

Update hour of code year

--- app/locale/en.coco.coffee
+++ app/locale/en.coco.coffee
@@ -2944,7 +2944,7 @@
     send: "Send Email"

   hoc_2018:
-    banner: "Welcome to Hour of Code 2019!" #
+    banner: "Welcome to Hour of Code 2019!"
     page_heading: "Your students will learn to code by building their own game!"
     step_1: "Step 1: Watch Video Overview"
     step_2: "Step 2: Try it Yourself"
@@ -2969,11 +2969,11 @@
     point4: "✓ Project-based courses"
     point5: "✓ Student tracking"
     point6: "✓ Full lesson plans"
-    title: "HOUR OF CODE 2018"
+    title: "HOUR OF CODE 2019" # {change}
     acronym: "HOC"

   hoc_2018_interstitial:
-    welcome: "Welcome to CodeCombat's Hour of Code 2018!"
+    welcome: "Welcome to CodeCombat's Hour of Code 2019!" # {change}
     educator: "I'm an educator"
     show_resources: "Show me teacher resources!"
     student: "I'm a student"


Update Indonesian translations on April 2021 Batch 2 (#6252)

--- app/locale/id.coco.coffee
+++ app/locale/id.coco.coffee
@@ -3160,8 +3160,8 @@
     join_now: "Gabung Sekarang"
     tagline: "CodeCombat AI League menggabungkan kurikulum yang disesuaikan dengan standar berbasis proyek kami, game coding berbasis petualangan yang menarik, dan turnamen global pengkodean AI tahunan kami ke dalam kompetisi akademik terorganisir yang tidak seperti yang lain."
     ladder_subheader: "Gunakan keahlian coding dan strategi pertempuran Anda untuk naik peringkat!"
-    earn_codepoints: "Dapatkan CodePoints dengan menyelesaikan level"
-#    codepoints: "CodePoints"
+    earn_codepoints: "Dapatkan PoinKode dengan menyelesaikan level"
+    codepoints: "PoinKode"
     free_1: "Akses arena multipemain kompetitif, papan peringkat, dan kejuaraan pengkodean global"
     free_2: "Dapatkan poin dengan menyelesaikan level latihan dan berkompetisi dalam pertandingan head-to-head"
     free_3: "Bergabunglah dengan tim coding kompetitif dengan teman, keluarga, atau teman sekelas"
@@ -3190,27 +3190,27 @@
     roster_management_subheader: "Lacak kinerja siswa dalam kurikulum dan dalam game, dan tambahkan atau hapus siswa dengan mudah."
     share_flyer: "Bagikan selebaran Liga AI kami dengan pendidik, administrator, orang tua, pelatih esports, atau orang lain yang mungkin tertarik."
     download_flyer: "Unduh Flyer"
-#    championship_summary: "The __championshipArena__ championship arena is now open! Battle it out for the month of __championshipMonth__ to win prizes in the __championshipArena__ __championshipType__."
-#    play_arena_full: "Play __arenaName__ __arenaType__"
-#    play_arena_short: "Play __arenaName__"
-#    arena_type_championship: "Championship Arena"
-#    arena_type_regular: "Multiplayer Arena"
+    championship_summary: "Arena kejuaraan __championshipArena__ sekarang dibuka! Bertarunglah di bulan __championshipMonth__ untuk memenangkan hadiah di __championshipArena__ __championshipType__."
+    play_arena_full: "Mainkan __arenaName__ __arenaType__"
+    play_arena_short: "Mainkan __arenaName__"
+    arena_type_championship: "Arena Kejuaraan"
+    arena_type_regular: "Arena Multiplayer (Banyak Pemain)"
     blazing_battle: "Pertempuran Berkobar"
-#    infinite_inferno: "Infinite Inferno"
-#    mages_might: "Mages' Might"
-#    sorcerers: "Sorcerers"
-#    giants_gate: "Giants' Gate"
-#    colossus: "Colossus"
-#    cup: "Cup"
-#    blitz: "Blitz"
-#    clash: "Clash"
-#    season1_announcement_1: "Time to put your coding skills to the test in our season 1 final arena. The Infinite Inferno Cup is live and offers a new challenge and a new leaderboard to climb."
-#    season1_announcement_2: "Need more practice? Stick with the Blazing Battle Arena to refine your skills. You have until April 30th to play both arenas. Note: arena balance adjustments may occur until April 23."
-#    season1_announcement_3: "Great prizes available for top performers in the Infinite Inferno Cup:"
-#    season1_prize_1: "$1,000 Scholarship"
-#    season1_prize_2: "RESPAWN Gaming Chair"
-#    season1_prize_3: "Custom CodeCombat Avatar"
-#    season1_prize_4: "And more!"
+    infinite_inferno: "Api Tak Berujung"
+    mages_might: "Penyihir Perkasa"
+    sorcerers: "Penyihir"
+    giants_gate: "Gerbang Raksasa"
+    colossus: "Colossus"
+    cup: "Piala"
+    blitz: "Menggempur"
+    clash: "Bentrokan"
+    season1_announcement_1: "Saatnya menguji kemampuan coding Anda di arena sesi final 1 kami. Infinite Inferno Cup sedang berlangsung dan menawarkan tantangan baru dan papan peringkat baru untuk didaki."
+    season1_announcement_2: "Perlu lebih banyak latihan? Tetap menggunakan Blazing Battle Arena untuk mengasah keterampilan Anda. Anda memiliki waktu hingga 30 April untuk memainkan kedua arena tersebut. Catatan: penyesuaian saldo arena dapat terjadi hingga 23 April."
+    season1_announcement_3: "Hadiah menarik tersedia untuk pemain terbaik di Infinite Inferno Cup:"
+    season1_prize_1: "Beasiswa $1,000"
+    season1_prize_2: "RESPAWN Kursi Permainan"
+    season1_prize_3: "Avatar CodeCombat Khusus"
+    season1_prize_4: "Dan banyak lagi!"

   tournament:
     mini_tournaments: "Turname Mini"


Update sv.coffee (#5673)

Update sv.coffee (#5673)

Filled in a few translations.

--- app/locale/sv.coco.coffee
+++ app/locale/sv.coco.coffee
@@ -2806,27 +2806,27 @@
     py_empty_block: "Tom $1. Sätt 4 mellanslag framför satserna inuti $2 satsen."
     fx_missing_paren: "Om du vill använda `$1` som en funktion behöver du`()`"
 #    unmatched_token: "Unmatched `$1`.  Every opening `$2` needs a closing `$3` to match it."
-    unterminated_string: "Oavslutat sträng. Lägg till en matchande `\"` i slutet av din sträng."
+    unterminated_string: "Oavslutad sträng. Lägg till en matchande `\"` i slutet av din sträng."
     missing_semicolon: "Saknar semikolon."
     missing_quotes: "Saknar citattecken. Prova `$1`"
     argument_type: "`$1`s argument `$2` borde ha typen `$3`, men fick `$4`: `$5`."
     argument_type2: "`$1`s argument `$2` borde ha typen `$3`, men fick `$4`."
 #    target_a_unit: "Target a unit."
     attack_capitalization: "Attackera $1, inte $2. (Versaler är viktiga.)"
-#    empty_while: "Empty while statement. Put 4 spaces in front of statements inside the while statement."
-#    line_of_site: "`$1`'s argument `$2` has a problem. Is there an enemy within your line-of-sight yet?"
-#    need_a_after_while: "Need a `$1` after `$2`."
-#    too_much_indentation: "Too much indentation at the beginning of this line."
-#    missing_hero: "Missing `$1` keyword; should be `$2`."
-#    takes_no_arguments: "`$1` takes no arguments."
-#    no_one_named: "There's no one named \"$1\" to target."
-#    separated_by_comma: "Function calls paramaters must be seperated by `,`s"
+    empty_while: "Tom while (medans) sats. Sätt 4 mellanslag innan satserna i while-satsen."
+    line_of_site: "`$1`'s argument `$2` har ett problem. Är det en fiende inom synhåll än?"
+    need_a_after_while: "Behöver en `$1` efter `$2`."
+    too_much_indentation: "För mycket indentering i början av den här raden."
+    missing_hero: "Saknar `$1` nyckelord; borde vara `$2`."
+    takes_no_arguments: "`$1` tar inga argument."
+    no_one_named: "Det finns ingen som heter \"$1\" att sikta på."
+    separated_by_comma: "Funktionparametrar måste separaras med kommatecken(`,`)"
 #    protected_property: "Can't read protected property: $1"
-#    need_parens_to_call: "If you want to call `$1` as function, you need `()`'s"
-#    expected_an_identifier: "Expected an identifier and instead saw '$1'."
-#    unexpected_identifier: "Unexpected identifier"
-#    unexpected_end_of: "Unexpected end of input"
-#    unnecessary_semicolon: "Unnecessary semicolon."
+    need_parens_to_call: "Om du vill anropa `$1` som en funktion så behöver du `()`"
+    expected_an_identifier: "En identifierare förväntades, såg istället '$1'."
+    unexpected_identifier: "Oväntad identifierare"
+    unexpected_end_of: "Oväntat slut på inmatning"
+    unnecessary_semicolon: "Onödigt semikolon."
 #    unexpected_token_expected: "Unexpected token: expected $1 but found $2 while parsing $3"
 #    unexpected_token: "Unexpected token $1"
 #    unexpected_token2: "Unexpected token"


update zh-HANS

update zh-HANS

--- app/locale/zh-HANS.coffee
+++ app/locale/zh-HANS.coffee
@@ -3038,12 +3038,12 @@
     project_stat_description: "学生作品数是学生已经创建的游戏开发和网页开发作品的总数。"
     no_teachers: "你目前没有管理其他老师。"

-#  interactives:
-#    phenomenal_job: "Phenomenal Job!"
-#    try_again: "Whoops, try again!"
-#    select_statement_left: "Whoops! Select a code statement before pressing Submit."
-#    fill_boxes: "Whoops, make sure to fill all boxes before hitting \"Submit.\""
-#    cannot_play_video: "Sadly, this video cannot be played in your area."
-#    console_instructions: "See why by opening your browser console: 1) Right click 2) Choose \"Inspect\" 3) Click the console tab."
-#    skip_video: "Skip video"
-#    unavailable: "Unavailable"
+  interactives:
+    phenomenal_job: "太棒了!"
+    try_again: "请重试!"
+    select_statement_left: "点击提交前请选择一条代码"
+    fill_boxes: "请确认在提交前完成所有的表单项目"
+    cannot_play_video: "抱歉，这个视频在您的地区无法播放"
+    console_instructions: "请按照一下步骤打开浏览器命令行查看原因：1）单击鼠标右键2）选择\"检查\"3）点击Console标签栏"
+    skip_video: "跳过视频"
+    unavailable: "无法获取资源"


sync codecombat repo

sync codecombat repo

--- app/locale/zh-HANS.coffee
+++ app/locale/zh-HANS.coffee
@@ -1,8 +1,8 @@
 module.exports = nativeDescription: "简体中文", englishDescription: "Chinese (Simplified)", translation:

   new_home:
-#    title: "CodeCombat - Coding games to learn Python and JavaScript"
-#    meta_description: "Learn typed code through a programming game. Learn Python, JavaScript, and HTML as you solve puzzles and learn to make your own coding games and websites."
+    title: "CodeCombat - 美国大学理事会认证硅谷原版青少年编程平台"
+    meta_description: "CodeCombat（中国官方网址：koudashijie.com）于2013年成立于美国硅谷，是美国大学理事会权威认证的青少年编程学习平台，学习者可以在CodeCombat学习后参加AP计算机考试，拿到美国和世界一流名校如斯坦福大学、哈佛大学、麻省理工学院等学分减免政策，是全球公认的权威计算机编程能力学习平台之一。"
     built_for_teachers_title: "一个以教师为中心的课程体系"
     built_for_teachers_blurb: "教孩子们写代码往往会觉得无从下手。 CodeCombat 旨在帮助所有的教育工作者传授学生学习和掌握当下最流行的两种计算机语言，JavaScript 和 Python。整个体系包含六门计算机科学课程，以及通过基于项目的游戏开发和网页开发单元巩固学习，教会孩子们一步步从基本语法到高级递归前进！"
     built_for_teachers_subtitle1: "计算机科学"
@@ -410,7 +410,7 @@
     teacher_list_resource_hub_3: "关卡解决方案，和"
     teacher_list_resource_hub_4: "资源汇总"
     teacher_list_resource_hub_5: "课程指导，课程活动和更多信息！"
-    teacher_additional_questions: "如果需要额外帮助或遇到问题，请联系 bill@codecombat.com。"
+    teacher_additional_questions: "如果需要额外帮助或遇到问题，请联系 china@codecombat.com。"
     dont_use_our_email_silly: "请填写家长的邮箱地址。"
     want_codecombat_in_school: "想接着玩CodeCombat?"
     eu_confirmation: "我同意 CodeCombat 在美国的服务器上存储我的数据"
@@ -548,7 +548,7 @@

   play_level:
     back_to_map: "返回地图"
-    directions: "方向"
+    directions: "游戏指引"
     edit_level: "编辑关卡"
     keep_learning: "不断学习"
     explore_codecombat: "探索CodeCombat"
@@ -738,8 +738,8 @@
     methods: "函数"
     events: "事件"
 #    handlers: "Handlers"
-#    properties: "Properties"
-#    snippets: "Snippets"
+    properties: "属性"
+    snippets: "字段"
     spawnable: "可生成物"
     html: "HTML"
     math: "数学"
@@ -770,7 +770,7 @@
     created_during_hoc: "在“编程一小时”中创建。"
     restart: "重新开始关卡"
     play: "开始关卡"
-    learn_about_ozaria: "Learn About Ozaria"
+    play_more_codecombat: "玩更多的 CodeCombat 关卡"
     default_student_instructions: "单击控制英雄，并取得胜利！"
     goal_survive: "生存。"
     goal_survive_time: "生存 __seconds__ 秒。"
@@ -897,7 +897,7 @@
     year_subscription: "年度订阅"
     year_price: "$__price__/年"
     support_part1: "付款时需要帮助? Email" # {change}
-    support_part2: "bill@codecombat.com"
+    support_part2: "china@codecombat.com"

   announcement:
     now_available: "现在订阅者可以获得更多内容"
@@ -1055,7 +1055,7 @@
     learn_more: "了解更多"
     main_title: "学习编程需要动手写大量代码"
     main_description: "CodeCombat让你带着微笑学习"
-    mission_link: "任务"
+    mission_link: "愿景"
     team_link: "团队"
     story_link: "历程"
     press_link: "联系方式"
@@ -1063,7 +1063,7 @@
     mission_description_1: "编程是一种魔法。这是一种从想象中创造万物的能力。我们开始了 CodeCombat 这个项目，是为了让学习者通过编写代码感受到他们指尖上的魔力。"
     mission_description_2: "同时，他们也能迅速学习，因为学习的方式变快了。学习就像是对话而不是阅读枯燥的手册。我们想将这种对话带给每所学校和每个学生，因为每个人都应有机会学习编程的魔法。"
     team_title: "与CodeCombat团队见面"
-    team_values: "我们期待开放的、互相尊敬的对话，好点子会得到采纳。我们决定深入市场调研，我们集中于提供实际性的结果。从我们的 CEO 到 Github 上的贡献者，每个人都亲历亲为，因为在团队中我们收获了成长与经验。"
+    team_values: "我们期待开放的、互相尊敬的对话，好点子会得到采纳。我们决定深入市场调研，我们集中于提供实际性的结果。从我们的 CEO 到 Github 上的贡献者，每个人都亲力亲为，因为在团队中我们收获了成长与经验。"
 #    nick_title: "Cofounder, CEO"
 #    matt_title: "Cofounder, CTO"
 #    cat_title: "Game Designer"
@@ -1103,17 +1103,17 @@
     community_subtitle: "超过 450 个志愿者帮助我们建设 CodeCombat，每周都有新成员加入！" # {change}
     community_description_3: "CodeCombat 是一个"
     community_description_link_2: "开源的社区项目"
-    community_description_1: "，上百名玩家创建了各种关卡，给我们的源代码添砖加瓦，添加新功能、修复Bug、测试、甚至是将其翻译为50种语言。职员、贡献者以及网站本身都在分享创意并奋斗中成长，这就是开源社区的力量。此网站在众多开源项目之上建立，我们为表感恩，也将网站开源奉献给社区，给好奇源码的玩家提供探索和实验的项目。每个人都能加入CodeCombat社区！看一下我们的" # {change}
+    community_description_1: "上百名玩家创建了各种关卡，给我们的源代码添砖加瓦，添加新功能、修复Bug、测试、甚至是将其翻译为50种语言。职员、贡献者以及网站本身都在分享创意并奋斗中成长，这就是开源社区的力量。此网站在众多开源项目之上建立，我们为表感恩，也将网站开源奉献给社区，给好奇源码的玩家提供探索和实验的项目。每个人都能加入CodeCombat社区！看一下我们的" # {change}
     community_description_link: "贡献者页面"
     community_description_2: "了解更多信息。"
     number_contributors: "超过 450 个志愿者将他们的知识和时间投入到这个项目中。"
     story_title: "我们已走过的历程"
     story_subtitle: "从2013年至今，CodeCombat已经从一组小草图成长为一个生动的、蓬勃发展的游戏。"
-    story_statistic_1a: "5,000,000+"
+    story_statistic_1a: "12,000,000+"
     story_statistic_1b: "总玩家"
     story_statistic_1c: "已经通过CodeCombat开始了他们的编程之旅"
     story_statistic_2a: "我们将这个游戏翻译为超过 50 种语言 —— 得益于来自"
-    story_statistic_2b: "200+ 个国家" # {change}
+    story_statistic_2b: "190+ 个国家" # {change}
     story_statistic_3a: "的玩家，他们总共写下了"
     story_statistic_3b: "10亿行代码和说明"
     story_statistic_3c: "，涵盖了多种编程语言。"
@@ -1159,7 +1159,7 @@
     low_price_title: "每个学生仅仅只要 __starterLicensePrice__ 元 "
     low_price_description: "学生入门许可证在购买后的 __starterLicenseLengthMonths__ 个月内有效."
     three_great_courses: "学生入门许可证中包含三个伟大的课程:"
-    license_limit_description: "老师最多可以购买 __maxQuantityStarterLicenses__ 个许可证. 你已经购买了 __quantityAlreadyPurchased__ 个. 如果你需要更多, 请联系 bill@codecombat.com. 学生入门许可证有效期为 __starterLicenseLengthMonths__ 个月."
+    license_limit_description: "老师最多可以购买 __maxQuantityStarterLicenses__ 个许可证. 你已经购买了 __quantityAlreadyPurchased__ 个. 如果你需要更多, 请联系 china@codecombat.com. 学生入门许可证有效期为 __starterLicenseLengthMonths__ 个月."
     student_starter_license: "学生入门许可"
     purchase_starter_licenses: "购买入门许可证"
     purchase_starter_licenses_to_grant: "购买入门许可证可被授权访问 __starterLicenseCourseList__"
@@ -1194,8 +1194,8 @@
   teachers_quote:
     subtitle: "将 CodeCombat 带到您的班级、俱乐部、学校甚至地区！" # {change}
     email_exists: "使用该账号的电子邮箱"
-    phone_number: "电话号码"
-    phone_number_help: "工作日时我们在哪可以找到您？"
+    phone_number: "手机号码"
+    phone_number_help: "工作日我们如何找到您？"
     primary_role_label: "您的主要职业"
     role_default: "选择职业"
     primary_role_default: "（请选择）"
@@ -1211,12 +1211,12 @@
     approve_funds: "批准资金"
     no_purchaser_role: "不参与购买决策"
     district_label: "地区"
-    district_name: "区"
+    district_name: "区/县"
     district_na: "不可用时请输入 N/A"
     organization_label: "学校："
-    school_name: "学校名称"
-    city: "城市"
-    state: "省" # {change}
+    school_name: "学校或机构名称"
+    city: "市（直辖市可填无）"
+    state: "省/直辖市" # {change}
     country: "国家"
     num_students_help: "您估计有多少学生加入CodeCombat？" # {change}
     num_students_default: "选择数量范围"
@@ -1253,7 +1253,7 @@
     create_account_subtitle: "在 CodeCombat 班级中使用老师专用工具。 创建班级添加学生、观察学生进度！"
     convert_account_title: "升级为老师账号"
     not: "不是"
-#    full_name_required: "First and last name required"
+    full_name_required: "姓和名是必填项"

   versions:
     save_version_title: "保存新版本"
@@ -1343,8 +1343,8 @@
     beautify: "利用标准编码格式美化您的代码。"
     maximize_editor: "最大化/最小化代码编辑器"

-#  cinematic:
-#    click_anywhere_continue: "click anywhere to continue"
+  cinematic:
+    click_anywhere_continue: "点击任意区域继续"

   community:
     main_title: "CodeCombat社区"
@@ -1740,7 +1740,7 @@
 #    not_assigned_modal_starter_body_2: "Purchase Starter Licenses to grant access to this course."
     not_assigned_modal_full_body_1: "本课程需要许可证才能使用。您没有足够的许可证, 因此无法将此课程分配给已选定的 __selected__ 名学生。"
     not_assigned_modal_full_body_2: "您当前仅有__numFullLicensesAvailable__个许可证可供使用 (__numStudentsWithoutFullLicenses__名学生目前没有许可证) 。"
-    not_assigned_modal_full_body_3: "请适量减少选定的学生数量, 或联系bill@codecombat.com寻求帮助。"
+    not_assigned_modal_full_body_3: "请适量减少选定的学生数量, 或联系china@codecombat.com寻求帮助。"
     assigned: "已添加"
     enroll_selected_students: "注册选中的学生"
     no_students_selected: "没有学生被选中。"
@@ -2314,12 +2314,12 @@
     left_xp_postfix: ""

   account:
-#    title: "Account"
-#    settings_title: "Account Settings"
-#    unsubscribe_title: "Unsubscribe"
-#    payments_title: "Payments"
-#    subscription_title: "Subscription"
-#    invoices_title: "Invoices"
+    title: "账户"
+    settings_title: "账户设置"
+    unsubscribe_title: "取消订阅"
+    payments_title: "支付"
+    subscription_title: "订阅"
+    invoices_title: "发票"
 #    prepaids_title: "Prepaids"
     payments: "支付方式"
     prepaid_codes: "预付费码"
@@ -2440,8 +2440,8 @@
     arithmetic: "四则运算"
     array_2d: "二维数组"
     array_index: "数组下标"
-#    array_iterating: "Iterating Over Arrays"
-#    array_literals: "Array Literals"
+    array_iterating: "数组迭代"
+    array_literals: "数组字面量"
     array_searching: "数组遍历"
     array_sorting: "数组排序"
     arrays: "数组"
@@ -2481,7 +2481,7 @@
     game_goals: "游戏目标"
 #    game_spawn: "Game Spawn"
     graphics: "图形"
-#    graphs: "Graphs"
+    graphs: "图"
     heaps: "堆"
     if_condition: "If条件语句"
     if_else_if: "If/Else If语句"
@@ -2502,7 +2502,7 @@
     jquery_selectors: "jQuery选择器"
     length: "数组长度"
 #    math_coordinates: "Coordinate Math"
-#    math_geometry: "Geometry"
+    math_geometry: "几何"
     math_operations: "数学程序库操作"
 #    math_proportions: "Proportion Math"
 #    math_trigonometry: "Trigonometry"
@@ -2527,7 +2527,7 @@
     while_condition_loops: "使用条件语句的While循环"
     while_loops_simple: "While循环"
     while_loops_nested: "While嵌套循环"
-#    xy_coordinates: "Coordinate Pairs"
+    xy_coordinates: "坐标对"
     advanced_strings: "高级字符串" # Rest of concepts are deprecated
     algorithms: "算法"
     boolean_logic: "布尔逻辑"
@@ -2913,7 +2913,7 @@
     projects_created: "学生作品数"
     other: "其他"
     notice: "以下学校管理员对您的课堂数据有查看权限："
-    add_additional_teacher: "需要添加其他的教师吗？请联系您的CodeCombat客户经理或发送电子邮件至bill@codecombat.com。 "
+    add_additional_teacher: "需要添加其他的教师吗？请联系您的CodeCombat客户经理或发送电子邮件至china@codecombat.com。 "
     license_stat_description: "可用许可证是教师可用的许可证总数，包括共享的许可证。"
     students_stat_description: "学生总数是所有教室的所有学生数，不管他们是否使用了许可证，都会被计算在内。"
     active_students_stat_description: "活跃学生数是在过去60天登录CodeCombat的学生人数。"


Update zh-HANT.coffee

Update zh-HANT.coffee

--- app/locale/zh-HANT.coffee
+++ app/locale/zh-HANT.coffee
@@ -289,40 +289,40 @@
     tip_open_source: "「程式之戰」100% 開源!"
     tip_beta_launch: "「程式之戰」在2013年10月進入BETA測試。"
     tip_think_solution: "思考解決方法而不是問題."
-#    tip_theory_practice: "In theory, there is no difference between theory and practice. But in practice, there is. - Yogi Berra"
-#    tip_error_free: "There are two ways to write error-free programs; only the third one works. - Alan Perlis"
-#    tip_debugging_program: "If debugging is the process of removing bugs, then programming must be the process of putting them in. - Edsger W. Dijkstra"
-#    tip_forums: "Head over to the forums and tell us what you think!"
-#    tip_baby_coders: "In the future, even babies will be Archmages."
-#    tip_morale_improves: "Loading will continue until morale improves."
-#    tip_all_species: "We believe in equal opportunities to learn programming for all species."
-#    tip_reticulating: "Reticulating spines."
-#    tip_harry: "Yer a Wizard, "
-#    tip_great_responsibility: "With great coding skill comes great debug responsibility."
-#    tip_munchkin: "If you don't eat your vegetables, a munchkin will come after you while you're asleep."
-#    tip_binary: "There are only 10 types of people in the world: those who understand binary, and those who don't."
-#    tip_commitment_yoda: "A programmer must have the deepest commitment, the most serious mind. ~ Yoda"
-#    tip_no_try: "Do. Or do not. There is no try. - Yoda"
-#    tip_patience: "Patience you must have, young Padawan. - Yoda"
-#    tip_documented_bug: "A documented bug is not a bug; it is a feature."
-#    tip_impossible: "It always seems impossible until it's done. - Nelson Mandela"
-#    tip_talk_is_cheap: "Talk is cheap. Show me the code. - Linus Torvalds"
-#    tip_first_language: "The most disastrous thing that you can ever learn is your first programming language. - Alan Kay"
-#    tip_hardware_problem: "Q: How many programmers does it take to change a light bulb?  A: None, it's a hardware problem."
-#    tip_hofstadters_law: "Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law."
-#    tip_premature_optimization: "Premature optimization is the root of all evil. - Donald Knuth"
-#    tip_brute_force: "When in doubt, use brute force. - Ken Thompson"
-#    tip_extrapolation: "There are only two kinds of people: those that can extrapolate from incomplete data..."
-#    tip_superpower: "Coding is the closest thing we have to a superpower."
-#    tip_control_destiny: "In real open source, you have the right to control your own destiny. - Linus Torvalds"
-#    tip_no_code: "No code is faster than no code."
-#    tip_code_never_lies: "Code never lies, comments sometimes do. — Ron Jeffries"
-#    tip_reusable_software: "Before software can be reusable it first has to be usable."
-#    tip_optimization_operator: "Every language has an optimization operator. In most languages that operator is ‘//’"
-#    tip_lines_of_code: "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. — Bill Gates"
-#    tip_source_code: "I want to change the world but they would not give me the source code."
-#    tip_javascript_java: "Java is to JavaScript what Car is to Carpet. - Chris Heilmann"
-#    tip_move_forward: "Whatever you do, keep moving forward. - Martin Luther King Jr."
+    tip_theory_practice: "理論上, 理論和實作之間是沒有區別. 但是實作上, 這兩者是有區別的. - Yogi Berra"
+    tip_error_free: "有兩種方式可以寫出沒有錯誤的程式; 但只有第三種可以達到預期效果. - Alan Perlis"
+    tip_debugging_program: "如果除錯是一種清除錯誤的過程, 那麼編寫程式就是一種放置錯誤的過程. - Edsger W. Dijkstra"
+    tip_forums: "前往論壇並且告訴我們你所思考的!"
+    tip_baby_coders: "在未來, 就算小孩也能成為大法師."
+    tip_morale_improves: "直到士氣提升之前，載入的動作將持續."
+    tip_all_species: "我們相信所有民族都有平等的機會學習編寫程式"
+    tip_reticulating: "網格狀鋸齒(指卡頓現象)"
+    tip_harry: "巫師, "
+    tip_great_responsibility: "隨著擁有強大的編程技巧，除錯的責任將越大."
+    tip_munchkin: "如果你不吃掉你的蔬菜，那小矮人將在你沈睡時找到你."
+    tip_binary: "只有2種人在這世上: 那些懂2進位的，和哪些不懂得."
+    tip_commitment_yoda: "一個程序員必須擁有強烈的責任感和一顆認真的心. ~ Yoda"
+    tip_no_try: "做，或者不做。這邊不存在嘗試的選項. - Yoda"
+    tip_patience: "年輕的學徒，你必須擁有耐心. - Yoda"
+    tip_documented_bug: "一個寫在文件裡的錯誤不是錯誤;它是功能."
+    tip_impossible: "它總是看起來不可能直到它成真那刻. - Nelson Mandela"
+    tip_talk_is_cheap: "多說無益，公開你的代碼. - Linus Torvalds"
+    tip_first_language: "你經歷的第一門程式語言是最慘痛的事情. - Alan Kay"
+    tip_hardware_problem: "Q: 換一顆燈泡需要多少位程序員?  A: 一位也不用, 它是個硬體問題."
+    tip_hofstadters_law: "Hofstadter定律: 完成一件複雜的事花費的時間總是超乎預期, 甚至你早已知道這個現象(Hofstadter定律)."
+    tip_premature_optimization: "過早的優化是萬惡之源. - Donald Knuth"
+    tip_brute_force: "當你游移不定時, 就是用暴力解. - Ken Thompson"
+    tip_extrapolation: "只有2種人在這世上: 一種人是能夠根據不完整資訊而推斷..."
+    tip_superpower: "編程讓我們最接近擁有超能力."
+    tip_control_destiny: "在真正的開源, 你有權利控制自己的命運. - Linus Torvalds"
+    tip_no_code: "在速度上，沒有任何代碼可以超過無代碼"
+    tip_code_never_lies: "代碼從不說謊, 但註釋偶爾會. — Ron Jeffries"
+    tip_reusable_software: "在軟體被重複使用前，它必須能用."
+    tip_optimization_operator: "每種語言都有一個優化的運算符號. 對大部份而言，那符號是‘//’"
+    tip_lines_of_code: "使用代碼行數來管理開發進度就好像使用秤重器來管理建造飛機. — Bill Gates"
+    tip_source_code: "我想改變世界但他們不給我源代碼"
+    tip_javascript_java: "Java和JavaScript的關係就好比馬和馬雲. - Chris Heilmann"
+    tip_move_forward: "不論你做啥, 持續前進. - Martin Luther King Jr."

   game_menu:
     inventory_tab: "倉庫"


Add tabIndex to button

Add tabIndex to button

--- lib/button.coffee
+++ lib/button.coffee
@@ -17,7 +17,9 @@
       props.classList.push 'm-primary' if @props.primary
       props.classList.push 'm-active' if @props.active

-      props['role'] = 'button'
+      props.tabIndex ?= 0
+      props.role ?= 'button'
+
       props['aria-disabled'] = !!@props.disabled

       props.onClick = do (onClick = props.onClick) =>


default title and content

default title and content

--- app/scripts/editor.coffee
+++ app/scripts/editor.coffee
@@ -14,14 +14,15 @@
 	constructor: (options={})->
 		@id = options.id
 		@status.new = !@id
+		@defaultTitle = options.title
+		@defaultContent = options.content
 		@newPostCallback = options.newPostCallback
 		@autosaveCallback = options.autosaveCallback
-		@articleCreateURL = options.articleCreateURL
-		@articleSaveURL = options.articleSaveURL
-		@articleDeleteURL = options.articleDeleteURL
 	init: ()->
 		self = @
-		$('#editor').html '

' if @status.new
+		$('#editor').html '

'
+		$('#editor-title').text @defaultTitle if @defaultTitle
+		$('#editor').html @defaultContent if @defaultContent
 		@autosave 5000
 		@update()
 		@checkTitleEmpty()


oops fix

oops fix

--- app/shared/helpers.coffee
+++ app/shared/helpers.coffee
@@ -56,7 +56,7 @@
   exports.stripTags = (str)-> if typeof str is 'string' then str.replace(/(<([^>]+)>)/g, '') else ''

   # Use when outputting string from untrusted source directly to the DOM, especially as JSON
-  helpers.sanitizeString = (string) ->
+  exports.sanitizeString = (string) ->
     string
       .replace(/\r\n/g, '\n')
       .replace(/<\/script>/g, '<\\/script>')


write permission is not required

write permission is not required

--- lib/config.coffee
+++ lib/config.coffee
@@ -24,7 +24,7 @@
 # Read saved config
 if !config?
   try
-    fs.accessSync defaultConfigPath, fs.R_OK | fs.W_OK
+    fs.accessSync defaultConfigPath, fs.R_OK
     config = CSON.parseCSONFile defaultConfigPath
     dbg.log "Config loaded from: #{defaultConfigPath}"
   catch e


Add an extra perf measurement

Add an extra perf measurement

--- js-library/app/js/jail_iframe/classes/performance_measurement.coffee
+++ js-library/app/js/jail_iframe/classes/performance_measurement.coffee
@@ -32,7 +32,7 @@
 .then( ->
   console.log document.readyState
   if window.performance && window.performance.timing
-    'fetchStart responseEnd domLoading domInteractive domContentLoadedEventEnd domComplete loadEventEnd'
+    'fetchStart responseEnd domLoading domInteractive domContentLoadedEventStart domContentLoadedEventEnd domComplete loadEventEnd'
     .split(' ').forEach (timing_event) ->
       add_existing_timing_event timing_event, window.performance.timing[timing_event]
   if FactlinkJailRoot.can_haz.log_jslib_loading_performance


add locale to cErrors

add locale to cErrors

#67

--- lib/errors.coffee
+++ lib/errors.coffee
@@ -20,5 +20,6 @@
   errors[error_name] = ChampionifyError.subclass error_name, ->
     @type = error_name
     @ua = [os.platform(), os.release()].join(' ')
+    @locale = T.locale

 module.exports = errors


Update format.coffee

Update format.coffee

--- lib/format.coffee
+++ lib/format.coffee
@@ -66,7 +66,7 @@

   subscribeToEvents: (editor) ->
     buffer = editor.getBuffer()
-    bufferSavedSubscription = @subscribe buffer, 'will-be-saved', => # 'on-will-save'
+    bufferSavedSubscription = @subscribe buffer, 'on-will-save', =>
       buffer.transact =>
         @formatJavascript(editor)


Use file's grammar to detect if it can be formatted.

Because the file extension may not always accurately describe a file's contents,
use the file's grammar. The user can now manually set the grammar of a file that
doesn't end with .json or .js and it can be formatted.

Also using the grammar to detect validity covers other javascript file
extensions such as .es6 and .jsx.

--- lib/format.coffee
+++ lib/format.coffee
@@ -1,6 +1,5 @@
 FileTypeNotSupportedView = require './not-supported-view'

-path = require 'path'
 jsbeautify = (require 'js-beautify').js_beautify

 module.exports =
@@ -28,9 +27,9 @@
     if !editor
       return

-    ext = path.extname editor.getTitle()
+    grammar = editor.getGrammar()?.scopeName

-    if ext == '.js' or ext == '.json'
+    if grammar is 'source.json' or grammar is 'source.js'
       @formatJavascript editor
     else
       notification = new FileTypeNotSupportedView(state)


fix to installer output

fix to installer output

--- lib/izpack.coffee
+++ lib/izpack.coffee
@@ -26,7 +26,7 @@
     path.exists path.join(dirs.app, 'LICENSE'), (exists) ->
       app.panels = []
       app.resources = []
-      app.packs = {}
+      app.packs = []
       app.panels.push name: 'panel', attrs: 'classname="HelloPanel"'
       if exists
         app.panels.push name: 'panel', attrs: 'classname="LicencePanel"'
@@ -35,6 +35,10 @@
       app.panels.push name: 'panel', attrs: 'classname="InstallPanel"'
       app.panels.push name: 'panel', attrs: 'classname="SimpleFinishPanel"'
       # TODO: <executable> that sets up os-dependent shit and compiles node if it needs to
-      app.packs.pack = name: pack.name, required: 'yes', preselected: 'yes', id: pack.name, file: src: dirs.temp, targetdir: '$INSTALL_PATH', override: 'asktrue'
-      console.log app.packs.pack
-      cb '<installation version="1.0">' + jsxml.obj_to_xml(app) + '</installation>'
+      mainpack =
+        name: 'pack'
+        attrs: 'name="' + pack.name+  '" required="yes" preselected="yes" id="' + pack.name + '"'
+      mainpack.children = [description: pack.description, name: 'file', attrs: 'src="' + dirs.temp + '" targetdir="$INSTALL_PATH" override="asktrue"']
+      app.packs.push mainpack
+
+      cb '<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?><installation version="1.0">' + jsxml.obj_to_xml(app) + '</installation>'


Change unless to simpler else

Change unless to simpler else

--- lib/kernel.coffee
+++ lib/kernel.coffee
@@ -30,7 +30,7 @@
         if @onlyConnect
           atom.notifications.addInfo 'Using custom kernel connection:',
               detail: @configPath
-        unless @onlyConnect
+        else
             if @language == 'python' and not @kernelSpec.argv?
                 commandString = "ipython"
                 args = [