Fix unsupressed developer warning in the tests.

--- tests/batman/view/loop_rendering_test.coffee
+++ tests/batman/view/loop_rendering_test.coffee
@@ -25,7 +25,7 @@
 asyncTest 'it should allow loops over undefined values', 3, ->
   source = '

'
   context = Batman()
-  #Batman.developer.suppress()
+  Batman.developer.suppress()
   helpers.render source, context, (node, view) ->
     names = $('p', view.get('node')).map(-> @innerHTML).toArray()
     deepEqual names, []


SocialWorker: Tests: Counter: replace daisy with async.series

--- workers/social/lib/social/models/counter.test.coffee
+++ workers/social/lib/social/models/counter.test.coffee
@@ -2,9 +2,9 @@
 JCounter = require './counter'

 # Helpers
-{ daisy,
-  expect,
-  generateRandomString,
+{ async
+  expect
+  generateRandomString
   checkBongoConnectivity } = require '../../../testhelper'

 NAMESPACES              = []
@@ -211,20 +211,18 @@
       COUNT = 5

       for i in [1..COUNT]
-        queue.push ->
+        queue.push (next) ->
           JCounter.increment options, (err) ->
             expect(err).to.not.exist
-            queue.next()
-
-      queue.push ->
+            next()
+
+      queue.push (next) ->
         JCounter.count options, (err, count) ->
           expect(err).to.not.exist
           expect(count).to.equal COUNT
-          done()
-
-      queue.push -> done()
-
-      daisy queue
+          next()
+
+      async.series queue, done

   describe 'workers.social.counter.reset', ->
@@ -236,37 +234,37 @@
     it 'should only reset the counter of given type', (done) ->

       queue = [
-        ->
+
+        (next) ->
           JCounter.increment options, (err, count) ->
             expect(err).to.not.exist
             expect(count).to.equal 1
-            queue.next()
-        ->
+            next()
+        (next) ->
           options.type = generateRandomString()
           JCounter.increment options, (err, count) ->
             expect(err).to.not.exist
             expect(count).to.equal 1
-            queue.next()
-        ->
+            next()
+        (next) ->
           JCounter.reset options, (err) ->
             expect(err).to.not.exist
-            queue.next()
-        ->
+            next()
+        (next) ->
           JCounter.count options, (err, count) ->
             expect(err).to.not.exist
             expect(count).to.equal 0
-            queue.next()
-        ->
+            next()
+        (next) ->
           options = { namespace: options.namespace }
           JCounter.count options, (err, count) ->
             expect(err).to.not.exist
             expect(count).to.equal 1
-            queue.next()
+            next()
+
       ]

-      queue.push -> done()
-
-      daisy queue
+      async.series queue, done

   describe 'workers.social.counter.setCount', ->
@@ -278,37 +276,37 @@
     it 'should set the provided count for given namespace and type', (done) ->

       queue = [
-        ->
+
+        (next) ->
           JCounter.setCount options, (err, count) ->
             expect(err).to.not.exist
             expect(count).to.equal 10
-            queue.next()
-        ->
+            next()
+        (next) ->
           options.type = generateRandomString()
           JCounter.setCount options, (err, count) ->
             expect(err).to.not.exist
             expect(count).to.equal 10
-            queue.next()
-        ->
+            next()
+        (next) ->
           JCounter.decrement options, (err, count) ->
             expect(err).to.not.exist
             expect(count).to.equal 9
-            queue.next()
-        ->
+            next()
+        (next) ->
           JCounter.setCount options, (err, count) ->
             expect(err).to.not.exist
             expect(count).to.equal 10
-            queue.next()
-        ->
+            next()
+        (next) ->
           JCounter.count options, (err, count) ->
             expect(err).to.not.exist
             expect(count).to.equal 10
-            queue.next()
+            next()
+
       ]

-      queue.push -> done()
-
-      daisy queue
+      async.series queue, done

 afterTests = ->
@@ -317,14 +315,12 @@

     queue = [ ]

-    NAMESPACES.forEach (namespace) -> queue.push ->
+    NAMESPACES.forEach (namespace) -> queue.push (next) ->
       JCounter.reset { namespace }, (err) ->
         expect(err).to.not.exist
-        queue.next()
-
-    queue.push -> done()
-
-    daisy queue
+        next()
+
+    async.series queue, done

 beforeTests()


Tidy up testing/logging

Tidy up testing/logging

--- services/filestore/app/coffee/S3PersistorManager.coffee
+++ services/filestore/app/coffee/S3PersistorManager.coffee
@@ -49,9 +49,9 @@
 			if res.statusCode != 200
 				logger.err bucketName:bucketName, key:key, fsPath:fsPath, "non 200 response from s3 putting file"
 				return callback("non 200 response from s3 on put file")
-			#LocalFileWriter.deleteFile fsPath, (err)->
-			logger.log res:res,  bucketName:bucketName, key:key, fsPath:fsPath,"file uploaded to s3"
-			callback(err)
+			LocalFileWriter.deleteFile fsPath, (err)->
+				logger.log res:res,  bucketName:bucketName, key:key, fsPath:fsPath,"file uploaded to s3"
+				callback(err)
 		putEventEmiter.on "error", (err)->
 			logger.err err:err,  bucketName:bucketName, key:key, fsPath:fsPath, "error emmited on put of file"
 			callback err
@@ -101,9 +101,10 @@
 			callback(err)

 	deleteDirectory: (bucketName, key, _callback)->
+		# deleteMultiple can call the callback multiple times so protect against this.
 		callback = (args...) ->
-			logger.log key: key, bucketName: bucketName, args: args, "calling delete callback"
 			_callback(args...)
+			_callback = () ->

 		logger.log key: key, bucketName: bucketName, "deleting directory"
 		s3Client = knox.createClient
@@ -111,7 +112,6 @@
 			secret: settings.filestore.s3.secret
 			bucket: bucketName
 		s3Client.list prefix:key, (err, data)->
-			logger.log data: data, key: key, bucketName: bucketName, "got file list"
 			keys = _.map data.Contents, (entry)->
 				return entry.Key
 			s3Client.deleteMultiple keys, callback


Ensure method calls.

Ensure method calls.

--- models/repository.coffee
+++ models/repository.coffee
@@ -24,7 +24,7 @@
 exports.Repository = Mongoose.model 'Repository', exports.RepositorySchema

 exports.Repository.prototype.toJSON = ->
-  obj = this.toObject
+  obj = this.toObject()
   if obj.builds && obj.builds.length
-    obj.builds = obj.builds.reverse
+    obj.builds = obj.builds.reverse()
   obj


seattle tweaks

seattle tweaks

Former-commit-id: be728bcd396f605c143e6e7999de85e63b49400d [formerly 82d5134d7396d2ecbc748c3935de965cf050d7aa] [formerly c54975ba8d85181dbfc3a02365997f293634b42d [formerly bab00df0646f4cf660d31e8497cbe5a0613fcf44]] [formerly 80bd3b5b8eaa117f1e5653b1ffeda90e85eb2e3d [formerly 4927e4904622d9e39e2fbf859fef36746957a2c8] [formerly 544d85ec597b0c8d8f61ecba2949a682a8aae4ab [formerly 544d85ec597b0c8d8f61ecba2949a682a8aae4ab [formerly 9fef30baedd8e2500f35b1e9fb499fa4d02af0bd]]]]
Former-commit-id: 945d4737afde6297176a7cb1e4745fab9c84a806 [formerly bde1ee1a439e5b3ea106ac5d23a409774674d353] [formerly ec267a8c5f3cdf7ab5a10648247ea9feccf82a7f [formerly 209aba61708897f9b3511227ea71f2e542bf768d]]
Former-commit-id: f1752209376d69549952ef410241ebb410ad3275 [formerly 23cfc6b707556b10b5b2b8a25038cec585899925]
Former-commit-id: b64d39a8d5d8afb354b2051b060d8002aebf15bf
Former-commit-id: 710e937636ddde873332396acabdc4081aae0a18

--- @client/customizations.coffee
+++ @client/customizations.coffee
@@ -318,6 +318,7 @@
           style:
             width: '100%'
             display: 'block'
+            paddingTop: 50

           src: asset('seattle2035/banner.png')

@@ -325,9 +326,9 @@

         DIV
           style:
-            backgroundColor: seattle2035_pink
-            color: seattle2035_cream
+            borderTop: "5px solid #{seattle2035_pink}"
             padding: '20px 0'
+            #marginTop: 50

           DIV
             style:
@@ -336,6 +337,7 @@

             DIV
               style:
+                color: seattle2035_pink
                 fontSize: 48
                 fontWeight: 600

@@ -345,17 +347,17 @@
               style:
                 fontSize: 24

-              "The "
-
-              A
-                href: 'google.com'
-                target: '_blank'
-
-                "Draft Environmental Impact Statement"
-
-              " is available for review."
-
-              BR null
+              # "The "
+
+              # A
+              #   href: 'google.com'
+              #   target: '_blank'
+
+              #   "Draft Environmental Impact Statement"
+
+              # " is available for review."
+
+              # BR null
               "Please leave your feedback on some of the pivotal questions listed below."


onchain conf header update

onchain conf header update

--- @client/customizations.coffee
+++ @client/customizations.coffee
@@ -2519,13 +2519,29 @@
             textAlign: 'center'

-          IMG
+
+
+
+          DIV
             style:
+              margin: "90px auto 140px auto"
+              width: '80%'
               position: 'relative'
-              top: -50
               zIndex: 3
-              width: '100%'
-            src: asset('bitcoin/OnChainConferences.svg')
+
+            IMG
+              style:
+                position: 'absolute'
+                left: '23%'
+                top: '-16%'
+                width: '7%'
+              src: asset('bitcoin/blockchainLogo.png')
+
+            IMG
+              style:
+                display: 'inline-block'
+                width: '100%'
+              src: asset('bitcoin/OnChainConferences2.svg')

           DIV


Changed google analytics flag for untranslated (de) content

--- app/assets/javascripts/analytics/presenter.coffee
+++ app/assets/javascripts/analytics/presenter.coffee
@@ -62,7 +62,9 @@
     ifvisible.onEvery 0.5, =>
       @pageViewTime += 500

-    if (!$('body').hasClass('de'))
+    if ($('body').hasClass('de'))
+      @automatedTranslation = 'de'
+    else
       @automatedTranslation = $('div').hasClass('Automated-translation')

   onBeforeUnload: =>


pass content to s3_uploads_complete trigger like others

--- app/assets/javascripts/s3_direct_upload.js.coffee
+++ app/assets/javascripts/s3_direct_upload.js.coffee
@@ -54,7 +54,7 @@
         data.context.remove() if data.context && settings.remove_completed_progress_bar # remove progress bar

         current_files.splice($.inArray(data, current_files), 1) # remove that element from the array
-        $uploadForm.trigger("s3_uploads_complete") unless current_files.length
+        $uploadForm.trigger("s3_uploads_complete", [content]) unless current_files.length

       fail: (e, data) ->
         content = build_content_object $uploadForm, data.files[0], data.result


add some notifications...

add some notifications...

--- app/assets/javascripts/views/login_view.js.coffee
+++ app/assets/javascripts/views/login_view.js.coffee
@@ -6,11 +6,13 @@
   loginSuccess: (user) ->
     Bandango.currentSession.logInAs user
     self.get("controller").transitionToRoute "dashboard"
+    alertify.success "Iniciaste sesión como #{user.username}"

   loginFailure: (response) ->
     self.setProperties
       sendingRequest: false
       error: response.responseJSON.message
+    alertify.error "Verifica tu usuario y contraseña"

   submit: ->
     self = @


All Comments Must Go!

All Comments Must Go!

--- mixirc/mixirc.coffee
+++ mixirc/mixirc.coffee
@@ -30,8 +30,6 @@
 	switch
 		when message.toLowerCase() is "sup " + ircBot.nick
 			ircBot.say to, "OH YOU KNOW JUST ENSLAVING THE HUMAN RACE"
-		# NOTE: The Regex below only returns true if the message is ".#"
-		# (# = number of any size)
 		when info.canHeart and heartMatch?
 			console.log "IRC => postAddCommentHeart: ", from, heartMatch[1],
 				message, channelId, info.mixlrUserLogin, info.mixlrAuthSession


another fix

another fix

--- salvus/page/r_misc.cjsx
+++ salvus/page/r_misc.cjsx
@@ -602,6 +602,7 @@
         full  : false

     handle_click : (e) ->
+        e.preventDefault()
         @props.flux.getProjectActions(@props.project_id).open_file
             path       : @props.path.join('/')
             foreground : require('misc_page').open_in_foreground(e)


Don't use host key checking, we can't be MITM'd

--- server/code/model/tool.coffee
+++ server/code/model/tool.coffee
@@ -34,7 +34,7 @@
   @dbClass: zDbTool

   rsync: (boxServer, callback) =>
-    child_process.exec "run-this-one rsync --delete -avz -e 'ssh -i /etc/custard/tools_rsa' /opt/tools/ tools@#{boxServer}:", callback
+    child_process.exec "run-this-one rsync --delete -avz -e 'ssh -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no -i /etc/custard/tools_rsa' /opt/tools/ tools@#{boxServer}:", callback

   gitCloneOrPull: (options, callback) ->
     {Box} = require 'model/box'


test readability++

test readability++

--- tests/V1.JsonQuery.Tests.coffee
+++ tests/V1.JsonQuery.Tests.coffee
@@ -208,6 +208,8 @@
       query.for(Expressions)
       query.exec().done (results) ->
         expect(results.length).to.equal(1)
-        expect(results[0].length).to.equal(41)
-        expect(results[0].at(1).get("Replies")).to.be.an.instanceof(V1.Collection)
-        expect(results[0].at(1).get("Replies").at(0).get("Author").get("WhoDat")).to.equal("Administrator")
+
+        expressions = results[0]
+        expect(expressions.length).to.equal(41)
+        expect(expressions.at(1).get("Replies")).to.be.an.instanceof(V1.Collection)
+        expect(expressions.at(1).get("Replies").at(0).get("Author").get("WhoDat")).to.equal("Administrator")


Init var before the black that will use it

--- client/app/libs/panel_router.coffee
+++ client/app/libs/panel_router.coffee
@@ -52,7 +52,6 @@

         # Updates the LayoutStore for each matched request
         @on 'route', (name, args) =>
-
             if name is 'default'
                 @current = {firstPanel: null, secondPanel: null}
                 url = @buildUrl
@@ -66,16 +65,15 @@
             [firstPanelInfo, secondPanelInfo] = @_processSubRouting name, args

             firstAction = @fluxActionFactory firstPanelInfo
+            if firstAction?
+                firstAction firstPanelInfo, 'first'
+
             secondAction = @fluxActionFactory secondPanelInfo
+            if secondAction?
+                secondAction secondPanelInfo, 'second'

             @previous = @current
             @current = firstPanel: firstPanelInfo, secondPanel: secondPanelInfo
-
-            if firstAction?
-                firstAction firstPanelInfo, 'first'
-
-            if secondAction?
-                secondAction secondPanelInfo, 'second'
             @trigger 'fluxRoute', @current

@@ -83,7 +81,6 @@
         Gets the Flux action to execute given a panel info.
     ###
     fluxActionFactory: (panelInfo) ->
-
         fluxAction = null
         pattern = @patterns[panelInfo?.action]


Remove second connect call.

Remove second connect call.

--- src/job-change-listener.coffee
+++ src/job-change-listener.coffee
@@ -40,5 +40,4 @@
     jobList[job.data.id] = job

 jobChangeListener = new JobChangeListener()
-jobChangeListener.connect(config.pulsarUrl + '/websocket', config.pulsarAuthToken)
 module.exports = jobChangeListener


add action hints

add action hints

--- src/layout/sprite_state.coffee
+++ src/layout/sprite_state.coffee
@@ -16,8 +16,8 @@
  make.buttons(
   program.name,
   make.columns 'program', [
-    program.name # edit the name
-    program._children() # delete the action
+    program.name # action: edit the name
+    program._children() # action: delete the action?
   ]
   my.language,
   (world, args) -> world.send 'edit', world.get('value')


Remove extra nesting level in integration test.

--- assets/scripts/spec/integration/build_spec.coffee
+++ assets/scripts/spec/integration/build_spec.coffee
@@ -5,53 +5,56 @@
     Ember.run -> Travis.reset()

 test "displaying information on build page", ->
-  visit('/travis-ci/travis-core/builds').then ->
-    visit('/travis-ci/travis-core/builds/1').then ->
-      listsRepos [
-        { slug: 'travis-ci/travis-hub',    build: { number: 4, url: '/travis-ci/travis-hub/builds/4',    duration: '1 min', finishedAt: '-' } }
-        { slug: 'travis-ci/travis-core',   build: { number: 1, url: '/travis-ci/travis-core/builds/1',   duration: '30 sec', finishedAt: '3 minutes ago' } }
-        { slug: 'travis-ci/travis-assets', build: { number: 3, url: '/travis-ci/travis-assets/builds/3', duration: '30 sec', finishedAt: 'a day ago' } }
+  visit('/travis-ci/travis-core/builds')
+  visit('/travis-ci/travis-core/builds/1')
+  andThen(->
+    listsRepos [
+      { slug: 'travis-ci/travis-hub',    build: { number: 4, url: '/travis-ci/travis-hub/builds/4',    duration: '1 min', finishedAt: '-' } }
+      { slug: 'travis-ci/travis-core',   build: { number: 1, url: '/travis-ci/travis-core/builds/1',   duration: '30 sec', finishedAt: '3 minutes ago' } }
+      { slug: 'travis-ci/travis-assets', build: { number: 3, url: '/travis-ci/travis-assets/builds/3', duration: '30 sec', finishedAt: 'a day ago' } }
+    ]
+
+    displaysRepository
+      href: '/travis-ci/travis-core'
+
+    displaysSummary
+      type: 'build'
+      id: 1
+      repo: 'travis-ci/travis-core'
+      commit: '1234567'
+      branch: 'master'
+      compare: '0123456..1234567'
+      finishedAt: '3 minutes ago'
+      duration: '30 sec'
+      message: 'commit message 1'
+
+    displaysSummaryGravatars
+      authorEmail: 'author@email.com'
+      committerEmail: 'committer@email.com'
+
+
+    displaysTabs
+      current: { href: '/travis-ci/travis-core' }
+      builds:  { href: '/travis-ci/travis-core/builds' }
+      build:   { href: '/travis-ci/travis-core/builds/1', active: true }
+      job:     { hidden: true }
+
+    listsJobs
+      table: '#jobs'
+      headers: ['Job', 'Duration', 'Finished', 'Ruby']
+      jobs: [
+        { color: 'green', id: 1, number: '1.1', repo: 'travis-ci/travis-core', finishedAt: '3 minutes ago', duration: '30 sec', rvm: 'rbx' }
+        { color: 'red',   id: 2, number: '1.2', repo: 'travis-ci/travis-core', finishedAt: '2 minutes ago', duration: '40 sec', rvm: '1.9.3' }
       ]

-      displaysRepository
-        href: '/travis-ci/travis-core'
+    listsJobs
+      table: '#allowed_failure_jobs'
+      headers: ['Job', 'Duration', 'Finished', 'Ruby']
+      jobs: [
+        { color: '', id: 3, number: '1.3', repo: 'travis-ci/travis-core', finishedAt: '-', duration: '-', rvm: 'jruby' }
+      ]
+  )

-      displaysSummary
-        type: 'build'
-        id: 1
-        repo: 'travis-ci/travis-core'
-        commit: '1234567'
-        branch: 'master'
-        compare: '0123456..1234567'
-        finishedAt: '3 minutes ago'
-        duration: '30 sec'
-        message: 'commit message 1'
-
-      displaysSummaryGravatars
-        authorEmail: 'author@email.com'
-        committerEmail: 'committer@email.com'
-
-
-      displaysTabs
-        current: { href: '/travis-ci/travis-core' }
-        builds:  { href: '/travis-ci/travis-core/builds' }
-        build:   { href: '/travis-ci/travis-core/builds/1', active: true }
-        job:     { hidden: true }
-
-      listsJobs
-        table: '#jobs'
-        headers: ['Job', 'Duration', 'Finished', 'Ruby']
-        jobs: [
-          { color: 'green', id: 1, number: '1.1', repo: 'travis-ci/travis-core', finishedAt: '3 minutes ago', duration: '30 sec', rvm: 'rbx' }
-          { color: 'red',   id: 2, number: '1.2', repo: 'travis-ci/travis-core', finishedAt: '2 minutes ago', duration: '40 sec', rvm: '1.9.3' }
-        ]
-
-      listsJobs
-        table: '#allowed_failure_jobs'
-        headers: ['Job', 'Duration', 'Finished', 'Ruby']
-        jobs: [
-          { color: '', id: 3, number: '1.3', repo: 'travis-ci/travis-core', finishedAt: '-', duration: '-', rvm: 'jruby' }
-        ]

 test "updating current build", ->
   visit('/travis-ci/travis-core').then ->


Fixed binding bug with new legend input fields

--- app/assets/javascripts/catalog_admin/items.coffee
+++ app/assets/javascripts/catalog_admin/items.coffee
@@ -202,6 +202,7 @@
   new_presenter = file_presenter_upload_finished($field, $result.processed_file)
   control.find("tr[data-file='#{file_id}']").replaceWith(new_presenter)
   activate_delete_file_buttons_for $field
+  activate_legend_image_input_for $field
   add_file_to_field($result.processed_file, $field)

 fileupload_error_for = ($field, $err)->


Add to unique unit tests

Add to unique unit tests

--- test/test-util.coffee
+++ test/test-util.coffee
@@ -3,4 +3,38 @@
     output = unique(input)
     expected = [5, 6, 7]

-    assert.deepEqual( output , expected)
+    assert.deepEqual(output , expected, "plain")
+
+    input = [5, 6, null, 7, 5, 5, 6, 7]
+    output = unique(input)
+    assert.deepEqual(output, expected, "with null")
+
+    input = [5]
+    output = unique(input)
+    expected = [5]
+    assert.deepEqual(output, expected, "one value")
+
+    input = [null, null, null]
+    output = unique(input)
+    expected = []
+    assert.deepEqual(output, expected, "only nulls")
+
+    input = [5, 6, 5, 6, 5, 6, "a"]
+    output = unique(input)
+    expected = [5, 6, "a"]
+    assert.deepEqual(output, expected, "mixed strings/integers can give weird results (1)")
+
+    input = [5, 6, 5, 6, 5, "6", "a"]
+    output = unique(input)
+    expected = [5, "6", "a"]
+    assert.deepEqual(output, expected, "mixed strings/integers can give weird results (2)")
+
+    input = ["5", 6, 5, 6, 5, "6", "a"]
+    output = unique(input)
+    expected = [5, "6", "a"]
+    assert.deepEqual(output, expected, "mixed strings/integers can give weird results (3)")
+
+    input = ["5", "5",  6, "5", "6", "5", "6", "a"]
+    output = unique(input)
+    expected = ["5", "6", "a"]
+    assert.deepEqual(output, expected, "mixed strings/integers can give weird results (4)")


Correcly bind this

Correcly bind this

--- services/GpxDownloader.coffee
+++ services/GpxDownloader.coffee
@@ -17,10 +17,10 @@
   #   takes an argument to the file path of the newly downloaded file.
   download: (cb) ->
     file = fs.createWriteStream(@dest())
-    request = http.get(@link, (response) ->
+    request = http.get(@link, (response) =>
       response.pipe file
-      file.on "finish", ->
-        file.close ->
+      file.on "finish", =>
+        file.close =>
           cb(@dest())
     )


pass the function pointer to `$(..).off`

--- app/assets/javascripts/md_simple_editor.js.coffee
+++ app/assets/javascripts/md_simple_editor.js.coffee
@@ -95,8 +95,10 @@
     txtarea.focus()
   txtarea.scrollTop = scrollPos

-$(document).on 'turbolinks:load page:load ready', ->
-  md_simple_editor()
-  $(document).off 'turbolinks:load page:load ready'
+initializeEditor = ->
+  md_simple_editor
+  $(document).off 'turbolinks:load page:load ready', initializeEditor
   $('.preview_md').click ->
     preview()
+
+$(document).on 'turbolinks:load page:load ready', initializeEditor


improved speed logging

improved speed logging

--- app/assets/javascripts/oxalis/model/binary.coffee
+++ app/assets/javascripts/oxalis/model/binary.coffee
@@ -90,8 +90,8 @@

     currentDate = new Date()
     interval = currentDate - @lastPingTime
-    if @queue.queue and @queue.queue.length > 0
-      console.log interval, @queueStatus - @queue.queue.length, @queue.queue[0].priority
+    #if @queue.queue and @queue.queue.length > 0
+      #console.log interval, @queueStatus - @queue.queue.length, @queue.queue[0].priority
     @queueStatus = @queue.queue.length
     @lastPingTime = currentDate


Update sprite after initialization

Update sprite after initialization

--- app/scripts/components/entities/LargeDrone.coffee
+++ app/scripts/components/entities/LargeDrone.coffee
@@ -26,6 +26,7 @@
         mine = c.obj
         return if mine.hidden
         mine.absorbDamage(300) # Mine collision on LargeDrone triggers explosion of mine
+    @updatedHealth()
     this

   updatedHealth: ->


Fix: 'webkitAudioContext' is deprecated

Fix: 'webkitAudioContext' is deprecated

--- app/application.coffee
+++ app/application.coffee
@@ -4,7 +4,7 @@
 module.exports = class Application

   constructor: ->
-    AudioContext = window.webkitAudioContext or window.AudioContext
+    AudioContext = window.AudioContext
     throw 'WebAudio support required' unless AudioContext
     context = new AudioContext
     @drone = new Drone context


Fix Page#dump().

Fix Page#dump().

--- application/chrome/content/wesabe/dom/Page.coffee
+++ application/chrome/content/wesabe/dom/Page.coffee
@@ -647,13 +647,12 @@
   # and whose png property is the path of the dumped PNG.
   dump: ->
     tryThrow 'Page.dump', =>
-      Dir.profile.child('wesabe-page-dumps').create()
-
-      html = folder.clone()
-      png = folder.clone()
+      folder = Dir.profile.child('wesabe-page-dumps')
+      folder.create()
+
       basename = "#{new Date().getTime()}-#{@document.title.replace /[^-_a-zA-Z0-9 ]/g, ''}"
-      html.append "#{basename}.html"
-      png.append "#{basename}.png"
+      html = folder.child("#{basename}.html")
+      png = folder.child("#{basename}.png")

       logger.debug 'Dumping contents of current page to ', html.path, ' and ', png.path
       File.write html, "<html>#{@document.documentElement.innerHTML}</html>"


Spy on the parser

Spy on the parser


* minor change

* minor change

--- src/markdown/ast-parser.coffee
+++ src/markdown/ast-parser.coffee
@@ -25,7 +25,7 @@
     out

   tok: ->
-    return '' if @token == undefined || !@token.hasOwnProperty('type')
+    return '' unless @token and @token.hasOwnProperty('type')

     switch (@token.type)
       when 'table'


fixing product name typo.

fixing product name typo.

--- assets/coffeescript/product_list.coffee
+++ assets/coffeescript/product_list.coffee
@@ -181,7 +181,7 @@
     img: "../media/images/additional_products/web/addon_oculus_dk2.png"
     order: 2
   }, {
-    id: "product_epson_mono"
+    id: "product_epson_bi"
     cost: 350
     label: "Epson Moverio BT-200 Binocular Mount Add-on"
     specs: "2 x camera mounts for Epson Moverio BT-200 with cables. Use with 120hz eye camera upgrade or existing 120hz eye camera from Pupil."


Repost works

Repost works

--- assets/javascripts/views/post.js.coffee
+++ assets/javascripts/views/post.js.coffee
@@ -38,6 +38,20 @@
       error: => @$el.show()

   repost: =>
+    data = {
+      permissions:
+        public: true
+      type: 'https://tent.io/types/post/repost/v0.1.0'
+      content:
+        entity: @post.get('entity')
+        id: @post.get('id')
+    }
+
+    console.log data
+    new HTTP 'POST', "#{TentStatus.config.current_tent_api_root}/posts", data, (post, xhr) =>
+      return unless xhr.status == 200
+      post = new TentStatus.Models.Post post
+      TentStatus.Views.Post.insertNewPost(post, @parentView.$el, @parentView)

   reply: =>

@@ -45,6 +59,7 @@
     return false unless post.isRepost()

     repost ?= _.find @parentView.posts.toArray() || [], ((p) => p.get('id') == post.get('content')['id'])
+    return false if post.get('id') == repost.get('id')
     return false unless repost
     _.extend( @context(repost), {
       parent: { name: post.name(), id: post.get('id') }


Handle component change events

Handle component change events

--- source/index.coffee
+++ source/index.coffee
@@ -116,6 +116,13 @@
           payload: { dictionary: @, key: key }
         return result

+      @forEach = (callback) =>
+        callback value, key, @ for own key, value of _definitions
+
+    reduce: (reduceFn, memo) ->
+      @forEach (value, key, target) -> memo = reduceFn memo, value, key, target
+      memo
+
     addListener: (args...) -> @emitter.addListener args...
     removeListener: (args...) -> @emitter.removeListener args...
     removeAllListeners: (args...) -> @emitter.removeAllListeners args...
@@ -141,6 +148,13 @@

       dependencies = @get(name).dependencies
       dependencies.reduce reduceDependencyCycles, []
+
+    getParentsOf: (dependee) ->
+      reduceFn = (memo, component, name) ->
+        return memo if component.dependencies.indexOf(dependee) is -1
+        return memo if memo.indexOf(name) isnt -1
+        memo.concat name
+      @reduce reduceFn, []

     assertDefined: (name) ->
       return if @isDefined(name)
@@ -174,14 +188,19 @@
       _components = new Components properties.components
       _promises = new Promises properties.promises

-      _components.addListener "set", (event) ->
-        _promises.remove event.payload.key
-
-      _components.addListener "remove", (event) ->
-        _promises.remove event.payload.key
+      _components.addListener "set", (event) =>
+        @handleComponentChange event.payload.key
+
+      _components.addListener "remove", (event) =>
+        @handleComponentChange event.payload.key

       $.defineProperty @, "components", enumerable: true, get: -> _components
       $.defineProperty @, "promises", enumerable: true, get: -> _promises
+
+    handleComponentChange: (key) ->
+      @promises.remove key
+      @components.getParentsOf(key).forEach (name) =>
+        @promises.remove name

     createComponentPromise: (name) ->
       $.createPromise (resolve, reject) =>


Invisible character tyranny

Invisible character tyranny

--- atom/browser/api/lib/app-command.coffee
+++ atom/browser/api/lib/app-command.coffee
@@ -1,55 +1,55 @@
 module.exports =
-    APPCOMMAND_BROWSER_BACKWARD:                 1
-    APPCOMMAND_BROWSER_FORWARD:                  2
-    APPCOMMAND_BROWSER_REFRESH:                  3
-    APPCOMMAND_BROWSER_STOP:                     4
-    APPCOMMAND_BROWSER_SEARCH:                   5
-    APPCOMMAND_BROWSER_FAVORITES:                6
-    APPCOMMAND_BROWSER_HOME:                     7
-    APPCOMMAND_VOLUME_MUTE:                      8
-    APPCOMMAND_VOLUME_DOWN:                      9
-    APPCOMMAND_VOLUME_UP:                        10
-    APPCOMMAND_MEDIA_NEXTTRACK:                  11
-    APPCOMMAND_MEDIA_PREVIOUSTRACK:              12
-    APPCOMMAND_MEDIA_STOP:                       13
-    APPCOMMAND_MEDIA_PLAY_PAUSE:                 14
-    APPCOMMAND_LAUNCH_MAIL:                      15
-    APPCOMMAND_LAUNCH_MEDIA_SELECT:              16
-    APPCOMMAND_LAUNCH_APP1:                      17
-    APPCOMMAND_LAUNCH_APP2:                      18
-    APPCOMMAND_BASS_DOWN:                        19
-    APPCOMMAND_BASS_BOOST:                       20
-    APPCOMMAND_BASS_UP:                          21
-    APPCOMMAND_TREBLE_DOWN:                      22
-    APPCOMMAND_TREBLE_UP:                        23
-    APPCOMMAND_MICROPHONE_VOLUME_MUTE:           24
-    APPCOMMAND_MICROPHONE_VOLUME_DOWN:           25
-    APPCOMMAND_MICROPHONE_VOLUME_UP:             26
-    APPCOMMAND_HELP:                             27
-    APPCOMMAND_FIND:                             28
-    APPCOMMAND_NEW:                              29
-    APPCOMMAND_OPEN:                             30
-    APPCOMMAND_CLOSE:                            31
-    APPCOMMAND_SAVE:                             32
-    APPCOMMAND_PRINT:                            33
-    APPCOMMAND_UNDO:                             34
-    APPCOMMAND_REDO:                             35
-    APPCOMMAND_COPY:                             36
-    APPCOMMAND_CUT:                              37
-    APPCOMMAND_PASTE:                            38
-    APPCOMMAND_REPLY_TO_MAIL:                    39
-    APPCOMMAND_FORWARD_MAIL:                     40
-    APPCOMMAND_SEND_MAIL:                        41
-    APPCOMMAND_SPELL_CHECK:                      42
-    APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE:43
-    APPCOMMAND_MIC_ON_OFF_TOGGLE:                44
-    APPCOMMAND_CORRECTION_LIST:                  45
-    APPCOMMAND_MEDIA_PLAY:                       46
-    APPCOMMAND_MEDIA_PAUSE:                      47
-    APPCOMMAND_MEDIA_RECORD:                     48
-    APPCOMMAND_MEDIA_FAST_FORWARD:               49
-    APPCOMMAND_MEDIA_REWIND:                     50
-    APPCOMMAND_MEDIA_CHANNEL_UP:                 51
-    APPCOMMAND_MEDIA_CHANNEL_DOWN:               52
-    APPCOMMAND_DELETE:                           53
-    APPCOMMAND_DWM_FLIP3D:                       54
+  APPCOMMAND_BROWSER_BACKWARD:                 1
+  APPCOMMAND_BROWSER_FORWARD:                  2
+  APPCOMMAND_BROWSER_REFRESH:                  3
+  APPCOMMAND_BROWSER_STOP:                     4
+  APPCOMMAND_BROWSER_SEARCH:                   5
+  APPCOMMAND_BROWSER_FAVORITES:                6
+  APPCOMMAND_BROWSER_HOME:                     7
+  APPCOMMAND_VOLUME_MUTE:                      8
+  APPCOMMAND_VOLUME_DOWN:                      9
+  APPCOMMAND_VOLUME_UP:                        10
+  APPCOMMAND_MEDIA_NEXTTRACK:                  11
+  APPCOMMAND_MEDIA_PREVIOUSTRACK:              12
+  APPCOMMAND_MEDIA_STOP:                       13
+  APPCOMMAND_MEDIA_PLAY_PAUSE:                 14
+  APPCOMMAND_LAUNCH_MAIL:                      15
+  APPCOMMAND_LAUNCH_MEDIA_SELECT:              16
+  APPCOMMAND_LAUNCH_APP1:                      17
+  APPCOMMAND_LAUNCH_APP2:                      18
+  APPCOMMAND_BASS_DOWN:                        19
+  APPCOMMAND_BASS_BOOST:                       20
+  APPCOMMAND_BASS_UP:                          21
+  APPCOMMAND_TREBLE_DOWN:                      22
+  APPCOMMAND_TREBLE_UP:                        23
+  APPCOMMAND_MICROPHONE_VOLUME_MUTE:           24
+  APPCOMMAND_MICROPHONE_VOLUME_DOWN:           25
+  APPCOMMAND_MICROPHONE_VOLUME_UP:             26
+  APPCOMMAND_HELP:                             27
+  APPCOMMAND_FIND:                             28
+  APPCOMMAND_NEW:                              29
+  APPCOMMAND_OPEN:                             30
+  APPCOMMAND_CLOSE:                            31
+  APPCOMMAND_SAVE:                             32
+  APPCOMMAND_PRINT:                            33
+  APPCOMMAND_UNDO:                             34
+  APPCOMMAND_REDO:                             35
+  APPCOMMAND_COPY:                             36
+  APPCOMMAND_CUT:                              37
+  APPCOMMAND_PASTE:                            38
+  APPCOMMAND_REPLY_TO_MAIL:                    39
+  APPCOMMAND_FORWARD_MAIL:                     40
+  APPCOMMAND_SEND_MAIL:                        41
+  APPCOMMAND_SPELL_CHECK:                      42
+  APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE:43
+  APPCOMMAND_MIC_ON_OFF_TOGGLE:                44
+  APPCOMMAND_CORRECTION_LIST:                  45
+  APPCOMMAND_MEDIA_PLAY:                       46
+  APPCOMMAND_MEDIA_PAUSE:                      47
+  APPCOMMAND_MEDIA_RECORD:                     48
+  APPCOMMAND_MEDIA_FAST_FORWARD:               49
+  APPCOMMAND_MEDIA_REWIND:                     50
+  APPCOMMAND_MEDIA_CHANNEL_UP:                 51
+  APPCOMMAND_MEDIA_CHANNEL_DOWN:               52
+  APPCOMMAND_DELETE:                           53
+  APPCOMMAND_DWM_FLIP3D:                       54


do not create _design view on every startup

--- db.coffee
+++ db.coffee
@@ -19,12 +19,6 @@

-db.save '_design/slides',
-  url:
-    map: (doc) ->
-      if doc.url
-        emit doc.url, doc
-
 db.getDocByURL = (url, cb) ->
   db.view "slides/url", key: url,  (err, docs) ->
     console.log "GETC", err, docs


addressing issue 4355 (#4414)

addressing issue 4355 (#4414)

Addressing changes needed to fix [issue 4355: problem enabling zoom on Image_url object](https://github.com/bokeh/bokeh/issues/4355#)

--- bokehjs/src/coffee/models/glyphs/image_url.coffee
+++ bokehjs/src/coffee/models/glyphs/image_url.coffee
@@ -42,8 +42,8 @@

   _map_data: () ->
     # XXX: remove this when `null` handling is improved.
-    ws = (if w? then w else NaN for w in @_w)
-    hs = (if h? then h else NaN for h in @_h)
+    ws = (if @_w? then @_w else NaN for x in @_x)
+    hs = (if @_h? then @_h else NaN for x in @_x)
     @sw = @sdist(@renderer.xmapper, @_x, ws, 'edge', @mget('dilate'))
     @sh = @sdist(@renderer.ymapper, @_y, hs, 'edge', @mget('dilate'))


Graphs are now registered as components, react accordingly

--- spec/network.coffee
+++ spec/network.coffee
@@ -7,9 +7,10 @@
       command: command
       payload: payload
     , '*'
-  receive = (expects, done) ->
+  receive = (protocol, expects, done) ->
     listener = (message) ->
       chai.expect(message).to.be.an 'object'
+      return if message.data.protocol isnt protocol
       expected = expects.shift()
       chai.expect(message.data).to.eql expected
       if expects.length is 0
@@ -38,7 +39,7 @@
               metadata: {}
               graph: 'foo'
         ]
-        receive expects, done
+        receive 'graph', expects, done
         send 'graph', 'clear',
           baseDir: '/noflo-runtime-iframe'
           id: 'foo'
@@ -60,7 +61,7 @@
               route: 5
             graph: 'foo'
         ]
-        receive expects, done
+        receive 'graph', expects, done
         send 'graph', 'addedge', expects[0].payload
     describe 'receiving an IIP', ->
       it 'should provide the IIP back', (done) ->
@@ -76,36 +77,8 @@
             metadata: {}
             graph: 'foo'
         ]
-        receive expects, done
+        receive 'graph', expects, done
         send 'graph', 'addinitial', expects[0].payload
-    describe 'removing a node', ->
-      it 'should remove the node and its associated edges', (done) ->
-        expects = [
-          protocol: 'graph'
-          command: 'removeedge'
-          payload:
-            src:
-              node: 'Foo'
-              port: 'out'
-            tgt:
-              node: 'Bar'
-              port: 'in'
-            metadata:
-              route: 5
-            graph: 'foo'
-        ,
-          protocol: 'graph'
-          command: 'removenode'
-          payload:
-            id: 'Bar'
-            component: 'core/Drop'
-            metadata: {}
-            graph: 'foo'
-        ]
-        receive expects, done
-        send 'graph', 'removenode',
-          id: 'Bar'
-          graph: 'foo'
     describe 'removing an IIP', ->
       it 'should provide the IIP back', (done) ->
         expects = [
@@ -120,12 +93,40 @@
             metadata: {}
             graph: 'foo'
         ]
-        receive expects, done
+        receive 'graph', expects, done
         send 'graph', 'removeinitial',
           tgt:
             node: 'Foo'
             port: 'in'
           graph: 'foo'
+    describe 'removing a node', ->
+      it 'should remove the node and its associated edges', (done) ->
+        expects = [
+          protocol: 'graph'
+          command: 'removeedge'
+          payload:
+            src:
+              node: 'Foo'
+              port: 'out'
+            tgt:
+              node: 'Bar'
+              port: 'in'
+            metadata:
+              route: 5
+            graph: 'foo'
+        ,
+          protocol: 'graph'
+          command: 'removenode'
+          payload:
+            id: 'Bar'
+            component: 'core/Drop'
+            metadata: {}
+            graph: 'foo'
+        ]
+        receive 'graph', expects, done
+        send 'graph', 'removenode',
+          id: 'Bar'
+          graph: 'foo'
     describe 'renaming a node', ->
       it 'should send the renamenode event', (done) ->
         expects = [
@@ -136,7 +137,7 @@
             to: 'Baz'
             graph: 'foo'
         ]
-        receive expects, done
+        receive 'graph', expects, done
         send 'graph', 'renamenode',
           from: 'Foo'
           to: 'Baz'
@@ -145,7 +146,7 @@
   describe 'Network protocol', ->
     # Set up a clean graph
     beforeEach (done) ->
-      waitFor = 4
+      waitFor = 8
       listener = (message) ->
         waitFor--
         return if waitFor


There is no second started

There is no second started

--- spec/network.coffee
+++ spec/network.coffee
@@ -228,22 +228,19 @@
           command: 'connect'
         ,
           protocol: 'network'
+          command: 'connect'
+        ,
+          protocol: 'network'
           command: 'data'
         ,
           protocol: 'network'
-          command: 'connect'
+          command: 'disconnect'
         ,
           protocol: 'network'
           command: 'data'
         ,
           protocol: 'network'
           command: 'disconnect'
-        ,
-          protocol: 'network'
-          command: 'disconnect'
-        ,
-          protocol: 'network'
-          command: 'started'
         ,
           protocol: 'network'
           command: 'stopped'


better comment

better comment

--- src/jquery.wow.popover.coffee
+++ src/jquery.wow.popover.coffee
@@ -54,6 +54,8 @@
       popover_left = elem_offset.left + (elem_wid / 2) - (300 / 2) # 300 = magic width number; change!
       window_wid = $(window).width()

+      # adjusted indicates if we needed to move the position of the
+      # popover to accomodate the browser margins.
       adjusted = false;
       if (popover_left < settings.side_margin)
         popover_left = settings.side_margin;


inspector test

inspector test

--- src/layout/test_layout.coffee
+++ src/layout/test_layout.coffee
@@ -58,10 +58,7 @@
     t.equal sprite.get('fill'), 'blue', 'fill'
     t.end()

-  test "sprite state", (t) ->
-    # t.ok sprite.get('state'), 'sprite state'
+  test "layout inspector", (t) ->
+    t.ok inspector = sprite.get('inspector'), 'made inspector'
     t.end()

-  test "layout inspector", (t) ->
-    t.end()
-


Mixpanel

Mixpanel

--- src/modules/top/topCtrl.coffee
+++ src/modules/top/topCtrl.coffee
@@ -47,7 +47,10 @@
       return

     $scope.openTweetWindow = ->
-      topService.openTweetWindow($scope.rateData.num[$scope.mySex], $scope.rankData[$scope.mySex][0].name)
+      topService.openTweetWindow(
+        $scope.rateData.num[$scope.mySex],
+        $scope.rankData[$scope.mySex][0].name
+      )
       return

     return


Reformat <script> tag

Reformat <script> tag

--- snippets/polymer-element.cson
+++ snippets/polymer-element.cson
@@ -47,8 +47,7 @@
         </style>
         $4
       </template>
-      <script src="$3">
-      </script>
+      <script src="$3"></script>
     </dom-module>
     """
   "polymer element template only":


Don’t start/stop text decorations at soft line breaks

Instead, deal with them at the start of the next line.

--- src/display-layer.coffee
+++ src/display-layer.coffee
@@ -629,7 +629,7 @@
             tagsToOpen.push(tagsToReopenAfterFold...)
             tagsToReopenAfterFold = null

-          if comparePoints(decorationIterator.getPosition(), bufferStart) is 0
+          if not metadata?.softLineBreak and comparePoints(decorationIterator.getPosition(), bufferStart) is 0
             tagsToClose.push(decorationIterator.getCloseTags()...)
             tagsToOpen.push(decorationIterator.getOpenTags()...)
             decorationIterator.moveToSuccessor()


remove sandbox stuff

remove sandbox stuff

--- spec/unit/routing.spec.coffee
+++ spec/unit/routing.spec.coffee
@@ -1,11 +1,9 @@
 describe "Request routing:", ->

-  sandbox = null
   requesthandler = null
   router = null

   beforeEach ->
-    sandbox = require 'sandboxed-module'
     requesthandler = jasmine.createSpyObj('requesthandler', [
       'root'
       'options'
@@ -19,7 +17,7 @@
       'notFound'
     ])

-    Router = sandbox.require '../../lib/router'
+    Router = require '../../lib/router'
     router = new Router()
     router.requesthandler = requesthandler
     router.initRoutes()


Add ReceiveRequest test file

Add ReceiveRequest test file


Frontend now uses secure websockets

Frontend now uses secure websockets

--- cmdr_web/src/scripts/websock.coffee
+++ cmdr_web/src/scripts/websock.coffee
@@ -12,7 +12,7 @@
   should_reconnect: yes
   ever_connected: no
   options:
-    host: "ws://#{window.location.host.split(":")[0]}:8000/"
+    host: "wss://#{window.location.host.split(":")[0]}/websock"
     connect_timeout: 1000
     reconnection_delay: 500
     max_delay: 15*1000


(- new api) Provide Paws#infect as convenience to consumers

--- Paws/Source/Paws.coffee
+++ Paws/Source/Paws.coffee
@@ -8,4 +8,5 @@
 Paws.parser  = require './parser.coffee'
 Paws.reactor = require './reactor.coffee'

+Paws.infect = (globals)-> @utilities.infect globals, this
 module.exports = Paws


remove debug code

remove debug code

--- app/controllers/classifier.coffee
+++ app/controllers/classifier.coffee
@@ -600,13 +600,10 @@
     $(".sim_details .planet-period").html(@planet_period + " days")

   showPlanetDetails:=>
-    console.log "showPlanetDetails() "
     $(".sim_details").hide()
     $(".planet_details").show()
     $(".planet_details .planet-rad").html( @subject.metadata.planet_rad + " Earth Radii" )
     $(".planet_details .planet-period").html( @subject.metadata.planet_period + " days" )
-    console.log 'RADIUS: ', +@subject.metadata.planet_rad
-    console.log 'PERIOD: ', +@subject.metadata.planet_period

   checkSupplementalTutorial: ->
     for classification_count in @supTutIntervals


fixed a bug for recovering the publishing of an algo that has a error in publishing

--- app/routes/algorithmRouter.coffee
+++ app/routes/algorithmRouter.coffee
@@ -8,7 +8,7 @@
 logger                = require '../logging/logger'
 nconf                 = require 'nconf'
 path                  = require 'path'
-ProcessingQueue       = require '../processingQueue/processingQueue'
+ResultHelper          = require '../helper/resultHelper'
 router                = require('express').Router()
 schemaValidator       = require '../validator/schemaValidator'
 ServicesInfoHelper    = require '../helper/servicesInfoHelper'
@@ -53,7 +53,7 @@
           createAlgorithm(req,res, route, identifier, imageName)
         else if(status.status.statusCode == 500)
           identifier = AlgorithmManagement.createIdentifier()
-          AlgorithmManagement.updateIdentifier(route, identifier)
+          AlgorithmManagement.updateIdentifier('/'+route, identifier)
           createAlgorithm(req, res, route, identifier, imageName)
         else
           response =
@@ -110,10 +110,7 @@
 router.post '/algorithms/:identifier/exceptions/:jobId', (req, res, next) ->
   AlgorithmManagement.recordException(req.params.identifier, req.text)
   process = QueueHandler.getDockerJob(req.params.jobId)
-  content = JSON.parse(fs.readFileSync(process.resultFile))
-  content.status = 'error'
-  content['errorMessage'] = 'There was an error in processing this request'
-  fs.writeFileSync(process.resultFile, JSON.stringify(content, null, '\t'),'utf8')
+  ResultHelper.removeResult(process)
   send200(res, {})

 router.get '/algorithms/:identifier/exceptions', (req, res) ->


Fix new discussion form linked image

Fix new discussion form linked image

--- app/talk/discussion-new-form.cjsx
+++ app/talk/discussion-new-form.cjsx
@@ -7,7 +7,6 @@
 Loading = require '../components/loading-indicator'
 PromiseRenderer = require '../components/promise-renderer'
 projectSection = require '../talk/lib/project-section'
-merge = require 'lodash.merge'

 module?.exports = React.createClass
   displayName: 'DiscussionNewForm'
@@ -40,10 +39,15 @@
     user_id = @props.user.id
     board_id = @props.boardId ? +form.querySelector('label > input[type="radio"]:checked').value
     body = commentText
-    focus_id = +@props.subject?.id
+    focus_id = subject?.id
     focus_type = 'Subject' if !!focus_id

-    comments = [merge({}, {user_id, body}, ({focus_id, focus_type} if !!focus_id))]
+    comment = if !!focus_id
+      {user_id, body, focus_id, focus_type}
+    else
+      {user_id, body}
+
+    comments = [comment]
     discussion = {title, user_id, board_id, comments}

     talkClient.type('discussions').create(discussion).save()


JS fix

JS fix

--- app/assets/javascripts/filters.js.coffee
+++ app/assets/javascripts/filters.js.coffee
@@ -14,7 +14,7 @@
     form = $(this).closest("form")
     $.post("/meetings/save_filter", form.serialize()).success ->
       disable_save_button()
-      false
+    false

 disable_save_button = () ->
   button = $("#save_filter")


Remove body-version, add prepareUpdate event

The body-version is none of our concern so remove it entirely but
provide a hook for update payload customization.

--- app/assets/javascripts/task_lists.coffee
+++ app/assets/javascripts/task_lists.coffee
@@ -46,8 +46,8 @@
   data =
     item:    item.attr('data-item-index')
     checked: if item.prop('checked') then 1 else 0
-    version: container.attr('data-version')

+  container.trigger('tasklist:prepareUpdate', data)
   disableTaskList(container)

   $.ajax
@@ -59,7 +59,6 @@
       if data.stale
         window.location.reload()
       else
-        container.attr('data-version', data.new_version)
         container.trigger('tasklist:updated', data)
     error: (e) ->
       console.log 'error', e


nick helper for KD

nick helper for KD

--- core/KD.coffee
+++ core/KD.coffee
@@ -82,6 +82,8 @@
   appClasses      : {}
   appScripts      : {}
   lastFuncCall    : null
+
+  nick:-> KD.whoami().profile.nickname

   whoami:-> KD.getSingleton('mainController').userAccount


KD: Remove appManager warning

KD: Remove appManager warning

--- core/KD.coffee
+++ core/KD.coffee
@@ -48,14 +48,6 @@
       KD.warn "Global \"event\" property is accessed. Did you forget a parameter in a DOM event handler?"
   catch e
     log "we fail silently!", e
-
-try
-  # warn when the global "event" property is accessed.
-  Object.defineProperty window, "appManager", get:->
-    console.trace()
-    KD.warn "window.appManager is deprecated, use KD.getSingleton(\"appManager\") instead!"
-catch e
-  log "we fail silently!", e

 @KD = $.extend (KD), do ->
   create = (constructorName, options, data)->


If there's not a known replacement, still mention it as deprecated, but suggest searching for it and posting back on tracking issue

--- src/hubot-scripts.coffee
+++ src/hubot-scripts.coffee
@@ -22,7 +22,11 @@

   replacement = replacements[filename]
   if replacement
-    robot.logger.warning "#{filename} in hubot-scripts.json has moved to its own package. Remove it from hubot-scripts.json and see #{replacement} for how to install the new version"
+    robot.logger.warning "#{filename} in hubot-scripts.json has moved to its own package. Remove it from hubot-scripts.json and see #{replacement} for how to install the new package."
     deprecatedScriptsUsed.push(filename)
+  else
+    inferredPackageName = "hubot-#{filename.replace('.coffee', '')}"
+    robot.logger.warning "#{filename} in hubot-scripts.json has been deprecated without a known replacement yet. You can try https://www.npmjs.com/search?q=#{inferredPackageName} or https://github.com/search?q=#{inferredPackageName}&type=Repositories or your favorite search engine. If you find a replacement or can't find a replacement, please leave a comment on https://github.com/github/hubot-scripts/issues/1641 with what you found."
+

 module.exports = HubotScripts


cleaning up the grammar  cson

cleaning up the grammar  cson

--- grammars/language-idris.cson
+++ grammars/language-idris.cson
@@ -1,92 +1,92 @@
 name: 'Idris'
 scopeName: 'source.idris'
-fileTypes: ["idr"],
+fileTypes: ['idr']
 patterns:
   [
     {
-      name: "operator.assignment"
-      match: "="
+      name: 'operator.assignment'
+      match: '='
     }
     {
-      name: "keyword.control.idris"
-      match: "\\b(if|then|else|do|let|in|data|codata|record|dsl)\\b"
+      name: 'keyword.control.idris'
+      match: '\\b(if|then|else|do|let|in|data|codata|record|dsl)\\b'
     }
     {
-      name: "keyword.control.idris"
-      match: "\\b(impossible|case|of|total|partial|mutual|infix|infixl|infixr)\\b"
+      name: 'keyword.control.idris'
+      match: '\\b(impossible|case|of|total|partial|mutual|infix|infixl|infixr)\\b'
     }
     {
-      name: "keyword.control.idris"
-      match: "\\b(where|with|syntax|proof|postulate|using|namespace|class|instance)\\b"
+      name: 'keyword.control.idris'
+      match: '\\b(where|with|syntax|proof|postulate|using|namespace|class|instance)\\b'
     }
     {
-      name: "keyword.control.idris"
-      match:  "\\b(public|private|abstract|implicit)\\b"
+      name: 'keyword.control.idris'
+      match:  '\\b(public|private|abstract|implicit)\\b'
     }
     {
-      name: "storage.type.builtin.idris"
-      match: "\\b(Type|Int|Nat|Integer|Float|Char|String|Ptr|Bits8|Bits16|Bits32|Bits64|Bool)\\b"
+      name: 'storage.type.builtin.idris'
+      match: '\\b(Type|Int|Nat|Integer|Float|Char|String|Ptr|Bits8|Bits16|Bits32|Bits64|Bool)\\b'
     }
     {
-      name: "constant.numeric.idris"
-      match: "\\b(S|Z)\\b"
+      name: 'constant.numeric.idris'
+      match: '\\b(S|Z)\\b'
     }
     {
-      match: "\\b([0-9]+|0([xX][0-9a-fA-F]+|[oO][0-7]+))\\b"
-      name: "constant.numeric.idris"
-      comment: "integer literal"
-    },
+      match: '\\b([0-9]+|0([xX][0-9a-fA-F]+|[oO][0-7]+))\\b'
+      name: 'constant.numeric.idris'
+      comment: 'integer literal'
+    }
     {
-      match: "\\b([0-9]+\\.[0-9]+([eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)\\b"
-      name: "constant.numeric.float.idris"
-      comment: "float literal"
-    },
+      match: '\\b([0-9]+\\.[0-9]+([eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)\\b'
+      name: 'constant.numeric.float.idris'
+      comment: 'float literal'
+    }
     {
-      name: "comment.line.idris"
-      match: "(--).*$\n?"
-      comment: "Line comment"
-    },
+      name: 'comment.line.idris'
+      match: '(--).*$\n?'
+      comment: 'Line comment'
+    }
     {
-      name: "comment.block.idris"
-      begin: "\\{-"
-      end: "-\\}"
-      comment: "Block comment"
-    },
+      name: 'comment.block.idris'
+      begin: '\\{-'
+      end: '-\\}'
+      comment: 'Block comment'
+    }
     {
-      name: "string.quoted.idris"
-      begin: "\""
+      name: 'string.quoted.idris'
+      begin: '"'
       beginCaptures:
         {
-          "0": { name: "punctuation.definition.string.begin.idris"}
+          0: { name: 'punctuation.definition.string.begin.idris' }
         }
-      end: "\""
+      end: '"'
       endCaptures:
         {
-          "0": { name: "punctuation.definition.string.end.idris"}
+          0: { name: 'punctuation.definition.string.end.idris' }
         }
       patterns:
         [
           {
-            name: "constant.character.escape.idris"
+            name: 'constant.character.escape.idris'
             match: "\\\\\""
           }
         ]
-    },
+    }
     {
-      name: "keyword.operator.function.infix.idris"
-      begin: "`"
+      name: 'keyword.operator.function.infix.idris'
+      begin: '`'
       beginCaptures:
         {
-          "0": { name: "punctuation.definition.entity.idris" }
+          0: { name: 'punctuation.definition.entity.idris' }
         }
-      end: "`",
+      end: '`'
       endCaptures:
         {
-          "0": { name: "punctuation.definition.entity.idris" }
+          0: { name: 'punctuation.definition.entity.idris' }
         }
     }
   ]
 repository:
   {
   }
-uuid: "4dd16092-ffa5-4ba4-8075-e5da9f368a72"
+uuid: '4dd16092-ffa5-4ba4-8075-e5da9f368a72'


promoted content tests links

promoted content tests links

--- apps/articles/test/client/article.coffee
+++ apps/articles/test/client/article.coffee
@@ -117,6 +117,7 @@

       Backbone.sync.args[0][2].success fabricate 'partner'
       Backbone.sync.args[4][2].success fabricate 'partner_profile'
+      $('.articles-promoted').attr('href').should.equal '/getty'
       $('.articles-promoted__name').text().should.equal 'Gagosian Gallery'

   describe 'promoted content auction', ->
@@ -133,5 +134,5 @@
     it 'displays promoted content banner for auction', ->

       Backbone.sync.args[5][2].success fabricate 'sale'
+      $('.articles-promoted').attr('href').should.equal '/sale/whtney-art-party'
       $('.articles-promoted__name').text().should.equal 'Whitney Art Party'
-


update hconfigure after latest mecano

update hconfigure after latest mecano

--- hadoop/lib/hconfigure.coffee
+++ hadoop/lib/hconfigure.coffee
@@ -3,7 +3,7 @@
 {EventEmitter} = require 'events'

 mecano = require 'mecano'
-conditions = require 'mecano/lib/conditions'
+conditions = require 'mecano/lib/misc/conditions'
 misc = require 'mecano/lib/misc'
 child = require 'mecano/lib/child'
 properties = require './properties'


default angle/velocity to 0 if no value is set

--- views/gorillas.coffee
+++ views/gorillas.coffee
@@ -508,6 +508,8 @@
       window.hide_player_field 'player_1', 'velocity'

       parameters = window.read_angle_and_velocity('player_1')
+      parameters.velocity = 0 unless parameters.velocity > 0
+      parameters.angle = 0 unless parameters.angle > 0
       window.clear_fields 'player_1'
       painter.throw_banana(parseInt(parameters.velocity), parseInt(parameters.angle), 1)


add max number default to spinbox

add max number default to spinbox

--- vendor/assets/javascripts/simple_form_extension/spinbox.coffee
+++ vendor/assets/javascripts/simple_form_extension/spinbox.coffee
@@ -2,8 +2,9 @@
   constructor: (@$el) ->
     @el = @$el[0]

-    @$el.spinbox()
-
+    @$el.spinbox(max: Number.POSITIVE_INFINITY)
+
+
 onPageReady ->
   $spinbox = $('.spinner-box-input')


Fixed unescaped path for prolog scripts

Fixed unescaped path for prolog scripts

--- lib/grammars.coffee
+++ lib/grammars.coffee
@@ -568,4 +568,4 @@
   Prolog:
     "File Based":
       command: "bash"
-      args: (context) -> ['-c', 'cd ' + context.filepath.replace(/[^\/]*$/, '') + '; swipl -f ' + context.filepath + ' -t main --quiet']
+      args: (context) -> ['-c', 'set -ex;cd \"' + context.filepath.replace(/[^\/]*$/, '') + '\"; swipl -f \"' + context.filepath + '\" -t main --quiet']


Turn on colored diagnostics for the C language family

--- lib/grammars.coffee
+++ lib/grammars.coffee
@@ -29,13 +29,13 @@
     if GrammarUtils.OperatingSystem.isDarwin()
       "File Based":
         command: "bash"
-        args: (context) -> ['-c', "xcrun clang -Wall -include stdio.h " + context.filepath + " -o /tmp/c.out && /tmp/c.out"]
+        args: (context) -> ['-c', "xcrun clang -fcolor-diagnostics -Wall -include stdio.h " + context.filepath + " -o /tmp/c.out && /tmp/c.out"]

   'C++':
     if GrammarUtils.OperatingSystem.isDarwin()
       "File Based":
         command: "bash"
-        args: (context) -> ['-c', "xcrun clang++ -Wc++11-extensions -Wall -include stdio.h -include iostream " + context.filepath + " -o /tmp/cpp.out && /tmp/cpp.out"]
+        args: (context) -> ['-c', "xcrun clang++ -fcolor-diagnostics -Wc++11-extensions -Wall -include stdio.h -include iostream " + context.filepath + " -o /tmp/cpp.out && /tmp/cpp.out"]

   CoffeeScript:
     "Selection Based":
@@ -176,13 +176,13 @@
     if GrammarUtils.OperatingSystem.isDarwin()
       "File Based":
         command: "bash"
-        args: (context) -> ['-c', "xcrun clang -Wall -include stdio.h -framework Cocoa " + context.filepath + " -o /tmp/objc-c.out && /tmp/objc-c.out"]
+        args: (context) -> ['-c', "xcrun clang -fcolor-diagnostics -Wall -include stdio.h -framework Cocoa " + context.filepath + " -o /tmp/objc-c.out && /tmp/objc-c.out"]

   'Objective-C++':
     if GrammarUtils.OperatingSystem.isDarwin()
       "File Based":
         command: "bash"
-        args: (context) -> ['-c', "xcrun clang++ -Wc++11-extensions -Wall -include stdio.h -include iostream -framework Cocoa " + context.filepath + " -o /tmp/objc-cpp.out && /tmp/objc-cpp.out"]
+        args: (context) -> ['-c', "xcrun clang++ -fcolor-diagnostics -Wc++11-extensions -Wall -include stdio.h -include iostream -framework Cocoa " + context.filepath + " -o /tmp/objc-cpp.out && /tmp/objc-cpp.out"]

   PHP:
     "Selection Based":


:art: improve, Change not enter insert-mode if nothing selected.

--- lib/operator.coffee
+++ lib/operator.coffee
@@ -854,12 +854,15 @@

   execute: ->
     @target.setOptions?(excludeWhitespace: true)
-    if @selectTarget()
-      @setTextToRegister @editor.getSelectedText()
-      text = if @target.isLinewise?() then "\n" else ""
-      for s in @editor.getSelections()
-        range = s.insertText(text, autoIndent: true)
-        s.cursor.moveLeft() unless range.isEmpty()
+    unless @selectTarget()
+      @activate('normal')
+      return
+
+    @setTextToRegister @editor.getSelectedText()
+    text = if @target.isLinewise?() then "\n" else ""
+    for s in @editor.getSelections()
+      range = s.insertText(text, autoIndent: true)
+      s.cursor.moveLeft() unless range.isEmpty()
     super

 class Substitute extends Change


changed function names style from camelCase to underscrore_notation

--- lib/assets/javascripts/_dom_parser.js.coffee
+++ lib/assets/javascripts/_dom_parser.js.coffee
@@ -5,43 +5,45 @@
   _get_parser: ->
     @_document_parser ?= @_parser_factory()

-  # fully taken from Turbolinks :)
+  # fully taken from Turbolinks (https://github.com/rails/turbolinks)
+  # and changed function names style
+  # by @igor-alexandrov request :)
   _parser_factory: ->
-    createDocumentUsingParser = (html) ->
+    create_document_using_parser = (html) ->
       (new DOMParser).parseFromString html, 'text/html'

-    createDocumentUsingDOM = (html) ->
+    create_document_using_DOM = (html) ->
       doc = document.implementation.createHTMLDocument ''
       doc.documentElement.innerHTML = html
       doc

-    createDocumentUsingWrite = (html) ->
+    create_document_using_write = (html) ->
       doc = document.implementation.createHTMLDocument ''
       doc.open 'replace'
       doc.write html
       doc.close()
       doc

-    # Use createDocumentUsingParser if DOMParser is defined and natively
+    # Use create_document_using_parser if DOMParser is defined and natively
     # supports 'text/html' parsing (Firefox 12+, IE 10)
     #
-    # Use createDocumentUsingDOM if createDocumentUsingParser throws an exception
+    # Use create_document_using_DOM if create_document_using_parser throws an exception
     # due to unsupported type 'text/html' (Firefox < 12, Opera)
     #
-    # Use createDocumentUsingWrite if:
+    # Use create_document_using_write if:
     #  - DOMParser isn't defined
-    #  - createDocumentUsingParser returns null due to unsupported type 'text/html' (Chrome, Safari)
-    #  - createDocumentUsingDOM doesn't create a valid HTML document (safeguarding against potential edge cases)
+    #  - create_document_using_parser returns null due to unsupported type 'text/html' (Chrome, Safari)
+    #  - create_document_using_DOM doesn't create a valid HTML document (safeguarding against potential edge cases)
     try
       if window.DOMParser
-        testDoc = createDocumentUsingParser '
test'
-        createDocumentUsingParser
+        testDoc = create_document_using_parser '
test'
+        create_document_using_parser
     catch e
-      testDoc = createDocumentUsingDOM '
test'
-      createDocumentUsingDOM
+      testDoc = create_document_using_DOM '
test'
+      create_document_using_DOM
     finally
       unless testDoc?.body?.childNodes.length is 1
-        return createDocumentUsingWrite
+        return create_document_using_write

 window._Wiselinks ?= {}


nw version accepts host:port as cmd line arg

--- client/init.coffee
+++ client/init.coffee
@@ -10,7 +10,7 @@
     socket = new FakeSocket; socket1 = new FakeSocket; socket.other = socket1; socket1.other = socket
     server = require './server'
 #     setTimeout (-> server.serve socket: socket1), 3000 # give the interpreter some time to start
-    hostPort = prompt 'Connect to:', localStorage?.hostPort or '127.0.0.1:4502'
+    hostPort = require('nw.gui').App?.argv?[0] or prompt 'Connect to:', localStorage?.hostPort or '127.0.0.1:4502'
     if !hostPort then return close()
     localStorage?.hostPort = hostPort
     server.serve socket: socket1, 'host:port': hostPort


Access package functions via atom.packages

--- lib/reporter.coffee
+++ lib/reporter.coffee
@@ -43,7 +43,7 @@

     # Private
     @getPackageData: ->
-      atom.getLoadedPackages().map (pack) ->
+      atom.packages.getLoadedPackages().map (pack) ->
         name: pack.name
         loadTime: pack.loadTime
         activateTime: pack.activateTime


Inline @minimumParams to prevent accessing globals at require time

--- lib/reporter.coffee
+++ lib/reporter.coffee
@@ -104,7 +104,14 @@

     @send: (params) =>
       if navigator.onLine
-        extend(params, @minimumParams)
+        extend(params, {
+          v: 1
+          aip: 1
+          tid: 'UA-3769691-33'
+          cid: localStorage.getItem('metrics.userId')
+          an: 'atom'
+          av: atom.getVersion()
+        })
         extend(params, @consentedParams()) if @consented()
         @request "https://ssl.google-analytics.com/collect?#{querystring.stringify(params)}" if @consented() or @isTelemetryConsentChoice(params)

@@ -125,13 +132,3 @@
         vp: "#{innerWidth}x#{innerHeight}"
         aiid: getReleaseChannel()
       }
-
-    @minimumParams =
-      {
-        v: 1
-        aip: 1
-        tid: 'UA-3769691-33'
-        cid: localStorage.getItem('metrics.userId')
-        an: 'atom'
-        av: atom.getVersion()
-      }


Refactor

Refactor

watch:*の挙動修正

--- gulp/tasks/watch.coffee
+++ gulp/tasks/watch.coffee
@@ -3,10 +3,10 @@

 gulp.task 'watch', (callback) ->
-  gulp.watch('./src/**', ['build'])
+  gulp.watch('./src/**/*', ['build'])

 gulp.task 'watch:develop', (callback) ->
-  gulp.watch('./src/**', ['develop'])
+  gulp.watch('./src/**/*', ['develop'])

 gulp.task 'watch:mocha', ->
   gulp.watch ['./src/**/*', './test/**/*'], ['mocha']


Viewer player count excludes masters

Viewer player count excludes masters

--- src/server/publications.coffee
+++ src/server/publications.coffee
@@ -22,7 +22,11 @@
   count = 0
   initializing = true

-  handle = Players.find(roomId: roomId).observeChanges
+  cursor = Players.find
+    roomId: roomId
+    isMaster: false
+
+  handle = cursor.observeChanges
     added: (id) =>
       count++
       unless initializing


Fix deactivation error when no emitter

Fix deactivation error when no emitter

--- lib/snippets.coffee
+++ lib/snippets.coffee
@@ -52,7 +52,7 @@
       @clearExpansions(editor)

   deactivate: ->
-    @emitter.dispose()
+    @emitter?.dispose()
     @emitter = null
     @editorSnippetExpansions?.clear()
     atom.config.transact => @subscriptions.dispose()


tests fixed.

tests fixed.

--- src/highlights.coffee
+++ src/highlights.coffee
@@ -34,7 +34,7 @@
   # tokens in the line.
   highlightSync: ({filePath, fileContents, scopeName}={}) ->
     @loadGrammarsSync()
-
+
     fileContents ?= fs.readFileSync(filePath, 'utf8') if filePath

     @_highlightCommon({filePath, fileContents, scopeName})
@@ -54,12 +54,14 @@
   # per line and each line will contain one or more <span> elements for the
   # tokens in the line. All grammar loading and fs operations are async so you can use this module in a server or busy process.
   highlight: ({filePath, fileContents, scopeName}={},cb) ->
+
+
     @loadGrammars((err) =>
       if err
         return cb(err)

-      if filePath
-        fs.readFile(filePath, 'utf8', (err,fileContents)->
+      if filePath and !fileContents
+        fs.readFile(filePath, 'utf8', (err,fileContents)=>
           if err
             return cb(err)

@@ -100,18 +102,12 @@
   # cb(err) - The callback so you know when it's done
   #
   requireGrammars: ({modulePath}={},cb) ->
-    console.log('REQUIRE GRAMMARS: start')
     @loadGrammars((err)=>
-
-      console.log('REQURE GRAMMARS: load grammars error? ',err)

       if err
         return cb(err)

       fs.stat(modulePath,(err,stat)=>
-
-        console.log('REQUIRE GRAMMARS: stat')
-        console.log('fs.stats on modulePath!!!!!! -------->',stat)

         if err
           return cb(err)
@@ -126,7 +122,6 @@

         grammarsDir = path.resolve(packageDir, 'grammars')
-        console.log('grammarsDir  --------> ',grammarsDir)
         @_registryLoadGrammarsDir(grammarsDir,cb)

       )
@@ -170,6 +165,7 @@
     )

   _highlightCommon:({filePath, fileContents, scopeName}={}) ->
+
     grammar = @registry.grammarForScopeName(scopeName)

     if !grammar
@@ -225,9 +221,6 @@

     @_loadingGrammars = [cb]
     callbacks = (err) =>
-      console.log('LOADGRAMMARS: finished loading. unrolling ',@_loadingGrammars)
-      if err
-        console.log(err+''+err.stack)

       cbs = @_loadingGrammars
       @_loadingGrammars = true


add ability to add a Color itself as a definition to a Palette


Remove a redundant request for the ou tree by search result module

As an alternative, we use the helper function id_name() that was recently
defined in the ou_tree module.  We can do this since ou_tree is a dependency of
the search bar module, which is a prerequisite of the search result module.

--- src/opac/search_result.coffee
+++ src/opac/search_result.coffee
@@ -17,10 +17,11 @@
 	'eg/eg_api'
 	'template'
 	'settings'
+	'opac/ou_tree'
 	'plugin'
 	'opac/cover_art'
 	'opac/page_bar'
-], ($, eg, _, rc) ->
+], ($, eg, _, rc, OU) ->

 	# ***
 	# Define the plugin content, a list view of title summaries.
@@ -95,7 +96,7 @@
 	# Define a function to show the call number of a title.
 	# We will format a call number as 'ou name / copy location / callnumber'.
 	# There are some provisos to the format, as follows.
-	show_callnumber = (cns, ou) ->
+	show_callnumber = (cns) ->
 		$cn = $('.callnumber', @)
 		if (cns).length
 			first = cns[0]
@@ -107,8 +108,8 @@

 			# * If all ou names do not match the first ou name,
 			# we will not show an ou name.
-			ou_name = ou[first.org_id].name
-			for cn in cns when ou[cn.org_id].name isnt ou_name
+			ou_name = OU.id_name first.org_id
+			for cn in cns when OU.id_name(cn.org_id) isnt ou_name
 				return $cn.text "#{first.copylocation} / #{first.callnumber}"
 				# >FIXME: Unfortunately,
 				# if the request ou ID corresponds to a leaf of the ou tree,
@@ -178,34 +179,30 @@
 			$this = @html(content)

 			# We now try searching the public catalogue with the new request.
-			@parallel 'search results',
-				result: eg.openils('search', request)
-				ou_tree: eg.openils 'actor.org_tree.retrieve'
-			, (x) ->
+			@openils 'search results', 'search', request, (result) ->

 				# Upon success or not,
 				# we will cache the result object and publish it to other plugins.
-				@data 'result', x.result
-				@publish 'opac.result', [x.result]
+				@data 'result', result
+				@publish 'opac.result', [result]

 				# If there are no results,
 				# we will show a *zero_hits* message and an optional *search_tips* message.
-				if x.result.count is 0
-					@append tpl_zero_hits query: x.result.query
+				if result.count is 0
+					@append tpl_zero_hits query: result.query
 					@append rc.search_tips if rc.search_tips
 					return

 				# Otherwise, we will build page bars to indicate the length of the result list.
-				$('#top_page_bar, #bottom_page_bar', @).page_bar {
+				$('#top_page_bar, #bottom_page_bar', @).page_bar
 					request: request
-					result:  x.result
-				}
+					result: result

 				# Finally, we will build the result list.
 				$result_list = $('.result_list', @).listview()
 				ou_id = Number request.org_unit
 				n = 0
-				for title_id in x.result.ids
+				for title_id in result.ids

 					# Record the maximum tab index.
 					maxTab = n if maxTab < ++n
@@ -262,7 +259,7 @@
 						, (y) ->
 							show_summary_info.call @, y.mvr if y.mvr
 							show_copy_counts.call @, y.nc, request.depth if y.nc
-							show_callnumber.call @, y.cns, x.ou_tree if y.cns
+							show_callnumber.call @, y.cns if y.cns
 							$result_list.listview 'refresh'

 				# We will focus the user on the first list element.
@@ -279,7 +276,7 @@
 				count = 1 + Number(request.offset) + $('li').index $li
 				if id and request
 					$this.publish 'opac.hold_create', [
-						x.result.count, count, id
+						result.count, count, id
 						request.org_unit, request.depth
 						$('img', $li).clone()
 					]
@@ -292,8 +289,9 @@
 				when 13 then $(@).click()
 			return false

-		# Upon the user clicking a title summary area,
-		# we will publish a request to create a hold.
+		# Upon the user clicking a title summary area, we will publish the
+		# informaiton to show details of the title and to prepare for a
+		# possible request to create a hold of the title.
 		@on 'click', 'li`', (e) =>
 			$this = $(@)
 			request = $this.data 'request'
@@ -305,7 +303,8 @@

 			if $li and (id = get_id $li) and request
 				count = offset + 1 + $('li').index $li
-				# >FIXME: it would be better for the main js file to load the required modules.
+				# >FIXME: would it be better for the main js file to load the
+				# required modules?
 				require ['login_window', 'opac/edit_hold'], ->
 					$('#edit_hold').edit_hold()
 					$('#login_window').login_window()


remap fix

remap fix

--- src/lib/entity.coffee
+++ src/lib/entity.coffee
@@ -213,9 +213,9 @@
         title: data[8]
         ornaments: data[9]
     }
-    result.mods = remapMods(data[10]) if data[10]
-    result.resonators = remapResos(data[11]) if data[11]
-    result.owner = data[12] if data[12]
+    result.mods = remapMods(data[11]) if data[11]
+    result.resonators = remapResos(data[12]) if data[12]
+    result.owner = data[13] if data[13]
     return result


backend_pubsub: run() should bail out early on invalid node form

--- src/xmpp/backend_pubsub.coffee
+++ src/xmpp/backend_pubsub.coffee
@@ -22,6 +22,9 @@

     run: (router, opts, cb) ->
         user = getNodeUser opts.node
+        unless user
+            return cb new errors.NotFound("Unrecognized node form")
+
         console.log 'PubsubBackend.run': opts, user: user
         @disco.findService user, (err, service) =>
             if err


Fix mentioning an entity with a path in the uri

--- assets/javascripts/helpers/url.js.coffee
+++ assets/javascripts/helpers/url.js.coffee
@@ -52,6 +52,7 @@
     _mentions = []
     _entities = {}

+    _from_urls = []
     unless options.exclude_urls == true
       for i in TentStatus.Helpers.extractUrlsWithIndices(text)
         entity = i.url
@@ -65,14 +66,15 @@
           scheme = 'https://'
           entity = scheme + entity

-        _mentions.push {
+        _from_urls.push {
           entity: entity
           url: entity.replace(/\/$/, '')
           text: original_text
           indices: i.indices
-        } unless _entities[entity]
+        } unless (_entities[entity] and options.uniq != false)
         _entities[entity] = true

+    _from_mentions = []
     if TentStatus.config.tent_host_domain
       _regex = new RegExp("([\\^]([a-z0-9]{2,}(?:\.#{TentStatus.config.tent_host_domain})?))(?!:\/\/)(?=[\\W]|$)")
       _offset = 0
@@ -91,13 +93,40 @@
         else
           entity = "https://#{entity}.#{TentStatus.config.tent_host_domain}"

-        _mentions.push {
+        should_skip = false
+
+        indexRangesForIndices = (indices) ->
+          _ranges = []
+          for start_index, index in indices
+            continue if index % 2
+            end_index = indices[index+1]
+            _ranges.push [start_index..end_index]
+          _ranges
+
+        _index_ranges = indexRangesForIndices(_indices)
+
+        doIndexRangesOverlap = (ranges_a, ranges_b) ->
+          for r_a in ranges_a
+            for r_b in ranges_b
+              return true if _.intersection(r_a, r_b).length
+          false
+
+        for i in _from_urls
+          i_index_ranges = indexRangesForIndices(i.indices)
+          if doIndexRangesOverlap(_index_ranges, i_index_ranges)
+            should_skip = true
+            break
+
+        continue if should_skip
+
+        _from_mentions.push {
           entity: entity
           text: original_text
           url: entity
           indices: _indices
-        } unless _entities[entity]
+        } unless (_entities[entity] and options.uniq != false)
         _entities[entity] = true

+    _mentions = _from_urls.concat(_from_mentions)
     _mentions


Comments are nice

Comments are nice

--- assets/javascripts/mailcatcher.js.coffee
+++ assets/javascripts/mailcatcher.js.coffee
@@ -286,10 +286,14 @@
       when "plain"
         message_iframe = $("#message iframe").contents()
         text = message_iframe.text()
+
+        # Escape special characters
         text = text.replace(/&/g, "&")
         text = text.replace(/</g, "<")
         text = text.replace(/>/g, ">")
         text = text.replace(/\n/g, "
")
+
+        # Autolink text
         text = text.replace(/((http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?)/g, """$1""")
         message_iframe.find("html").html("#{text}")


Fixed tetherOptions

Fixed tetherOptions

Drop option 'tetherOptions: {}' wasn't being passed properly to underlying Tether instance.

--- coffee/drop.coffee
+++ coffee/drop.coffee
@@ -138,8 +138,8 @@
         enabled: false
         constraints: constraints

-      if @options.tether isnt false
-        @tether = new Tether extend {}, options, @options.tether
+      if @options.tetherOptions isnt false
+        @tether = new Tether extend {}, options, @options.tetherOptions

     setupEvents: ->
       return unless @options.openOn


Send record to buildURL method when it's available

For some cases (like coming env vars) we will need to also pass a
repository id to the URL, so I'm passing it from createRecord and other
methods which handle records.

--- assets/scripts/lib/travis/adapter.coffee
+++ assets/scripts/lib/travis/adapter.coffee
@@ -1,3 +1,5 @@
+get = Ember.get
+
 Travis.Adapter = Ember.RESTAdapter.extend
   ajax: (url, params, method) ->
     Travis.ajax.ajax(url, method || 'get', data: params)
@@ -17,7 +19,7 @@
     records.load(klass, dataToLoad)
     @addToRecordArrays(records.get('content'))

-  buildURL: ->
+  buildURL: (klass, id, record) ->
     @_super.apply(this, arguments).replace(/\.json$/, '')

   didFind: (record, id, data) ->
@@ -55,7 +57,6 @@
     for record in records
       record.constructor.addToRecordArrays(record)

-
   sideload: (klass, data) ->
     for name, records of data
       records = [records] unless Ember.isArray(records)
@@ -66,4 +67,24 @@
           record = type.findFromCacheOrLoad(record)
           @addToRecordArrays(record)

+  find: (record, id) ->
+    url = @buildURL(record.constructor, id, record)
+    self = this
+    @ajax(url).then (data) ->
+      self.didFind record, id, data
+      record

+  createRecord: (record) ->
+    url = @buildURL(record.constructor, undefined, record)
+    self = this
+    @ajax(url, record.toJSON(), "POST").then (data) ->
+      self.didCreateRecord record, data
+      record
+
+  deleteRecord: (record) ->
+    primaryKey = get(record.constructor, "primaryKey")
+    url = @buildURL(record.constructor, get(record, primaryKey), record)
+    self = this
+    @ajax(url, record.toJSON(), "DELETE").then (data) -> # TODO: Some APIs may or may not return data
+      self.didDeleteRecord record, data
+      return


Add shooting condition to uploaded images

--- view/src/coffee/uploader.coffee
+++ view/src/coffee/uploader.coffee
@@ -37,20 +37,23 @@
     methods:
       push: (r) ->
         @results.push(r)
-
+COLUMNS = ['checkbox', 'fileName', 'cond.fNumber', 'cond.focal', 'cond.iso', 'dateTime', 'createdAt']
 renderImages = ->
   new Vue
     el: '#images'
     data:
-      columns: ['checkbox', 'fileName', 'dateTime', 'createdAt']
+      columns: COLUMNS
       checkedRows: []
       allChecked: false
       options:
-        sortable: ['fileName', 'dateTime', 'createdAt']
+        sortable: COLUMNS
         orderBy: {ascending: false, column: 'dateTime'}
         perPage: 100
         headings:
           checkbox: (h) -> createCheckbox(h, @)
+          'cond.fNumber': 'F'
+          'cond.focal': 'Focal'
+          'cond.iso': 'ISO'
           fileName: 'Name'
           dateTime: 'ShootingTime'
           createdAt: 'UploadingTime'


Adds a callback option to PreviewWindow.refresh

--- app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee
+++ app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee
@@ -43,15 +43,17 @@
     else
       $("#alchemyPreviewWindow").dialog "open"

-  refresh: ->
+  refresh: (callback) ->
     $iframe = $("#alchemyPreviewWindow")
     $spinner = $(".preview-refresh-spinner")
     $refresh = $('.ui-dialog-titlebar-refresh')
     $spinner.show()
     $refresh.hide()
-    $iframe.load ->
+    $iframe.load (e) ->
       $spinner.hide()
       $refresh.show()
+      if callback
+        callback.call(e, $iframe)
     $iframe.attr("src", $iframe.attr("src"))
     true


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/Physical.coffee
+++ src/Physical.coffee
@@ -7,13 +7,16 @@

   window.Physical = (I, self) ->
     $.reverseMerge I,
+      density: 1.0
       dynamic: false
+      friction: 0.1
+      restitution: 0.5
       rotatable: false

     fixDef = new b2FixtureDef()
-    fixDef.density = 1.0
-    fixDef.friction = 0.3
-    fixDef.restitution = 0.2
+    fixDef.density = I.density
+    fixDef.friction = I.friction
+    fixDef.restitution = I.restitution
     fixDef.shape = new b2PolygonShape()
     fixDef.shape.SetAsBox(I.width / 2 * SCALE, I.height / 2 * SCALE)

@@ -35,6 +38,8 @@
     body = I.world.CreateBody(bodyDef)
     body.CreateFixture(fixDef)

+    body.SetUserData(self)
+
     self.bind "step", ->
       I.x = (body.GetPosition().x / SCALE) - (I.width / 2)
       I.y = (body.GetPosition().y / SCALE) - (I.height / 2)


* clone default property value if the value is object when initializing


+ skipDefaultValue argument to exportTo and mergeTo function

--- src/abstract.coffee
+++ src/abstract.coffee
@@ -2,6 +2,7 @@
 isFunction      = require 'util-ex/lib/is/type/function'
 isObject        = require 'util-ex/lib/is/type/object'
 isString        = require 'util-ex/lib/is/type/string'
+isBoolean       = require 'util-ex/lib/is/type/boolean'
 isArray         = require 'util-ex/lib/is/type/array'
 deepEqual       = require 'deep-equal'
 getkeys         = Object.keys
@@ -41,27 +42,43 @@
     @assignPropertyTo(@, options, name, value, attrs, skipDefaultValue)
     return

-  mergeTo: (dest, aExclude)->
-    dest?= {}
+  mergeTo: (dest, aExclude, skipDefaultValue)->
+    if isArray dest
+      aExclude = dest
+      dest = {}
+    else if isBoolean dest
+      skipDefaultValue = dest
+      aExclude = []
+      dest = {}
+
     if isString aExclude
       aExclude = [aExclude]
+    else if isBoolean aExclude
+      skipDefaultValue = aExclude
+      aExclude = []
     else if not isArray aExclude
       aExclude = []
+
+    dest?= {}

     vAttrs = @getProperties()
     for k,v of vAttrs
       continue if k in aExclude
       continue if v and v.name and (v.name in aExclude)
       if !dest.hasOwnProperty(k)
-        @assignPropertyTo(dest, @, k, @[k], vAttrs, true)
+        @assignPropertyTo(dest, @, k, @[k], vAttrs, skipDefaultValue)
     dest

-  exportTo: (dest, aExclude)->
-    dest?= {}
+  exportTo: (dest, aExclude, skipDefaultValue)->
     if isString aExclude
       aExclude = [aExclude]
+    else if isBoolean aExclude
+      skipDefaultValue = aExclude
+      aExclude = []
     else if not isArray aExclude
       aExclude = []
+    dest?= {}
+    skipDefaultValue?= true

     vAttrs = @getProperties()
     for k,v of vAttrs
@@ -69,11 +86,11 @@
       continue if k in aExclude
       continue if v and v.name and (v.name in aExclude)
       if !dest.hasOwnProperty(k)
-        @assignPropertyTo(dest, @, k, @[k], vAttrs, true, true)
+        @assignPropertyTo(dest, @, k, @[k], vAttrs, skipDefaultValue, true)
     dest

   toObject: (options)->
-    @exportTo(options, null, true)
+    @exportTo(options)

   toJSON: ->@toObject()


fix (#6391)

fix (#6391)

--- app/views/ladder/components/Leaderboard.coffee
+++ app/views/ladder/components/Leaderboard.coffee
@@ -162,13 +162,18 @@
   handleClickPlayerName: (id) ->
     if me.isAdmin()
       leaderboards = @leaderboards.topPlayers.models
-      player = new User _id: leaderboards[id].get('creator')
       if @tournament
         session = new LevelSession _id: leaderboards[id].get('levelSession')
       else
         session = new LevelSession _id: leaderboards[id].get('_id')
-      models = [session, player]
-      @openModalView new ModelModal models: models
+      @supermodel.loadModel session
+      @listenToOnce session, 'sync', (_session) =>
+        if _session.get('source')?.name
+          models = [_session]
+        else
+          player = new User _id: leaderboards[id].get('creator')
+          models = [session, player]
+        @openModalView new ModelModal models: models
     else if me.isTeacher()
       ;
     else


fixed typo

fixed typo

--- plugins/image.coffee
+++ plugins/image.coffee
@@ -56,7 +56,7 @@

-                    <form action=\"#{widget.options.searchUrl}/?page=1&length=4\" tpye=\"post\" id=\"search_form\">
+                    <form action=\"#{widget.options.searchUrl}/?page=1&length=4\" type=\"post\" id=\"search_form\">
                         <input type=\"text\" class=\"searchInput\" /><input type=\"submit\" class=\"searchButton\" value=\"OK\"/>
                     </form>


Redraw editors when panel appears

Redraw editors when panel appears

If not done, the editors have zero height.

--- src/app/config-view.coffee
+++ src/app/config-view.coffee
@@ -52,6 +52,8 @@
       @panels.children().hide()
       @panelMenu.children('.active').removeClass('active')
       @panelsByName[name].show()
+      for editorElement in @panelsByName[name].find(".editor")
+        $(editorElement).view().redraw()
       @panelMenu.children("[name='#{name}']").addClass('active')
       @activePanelName = name
       @panelToShow = null


make fatal query errors temporary, due to rare race condition

--- src/smc-util/synctable.coffee
+++ src/smc-util/synctable.coffee
@@ -174,6 +174,10 @@

         # actually try to connect
         do_connect = =>
+            if not @_opts.no_sign_in
+                if not @_opts.client.is_signed_in()
+                    cb("not signed in but need to be")
+                    return
             if give_up_timer
                 clearInterval(give_up_timer)
             @_opts.connect (err) =>
@@ -262,6 +266,9 @@
     _connect: (cb) =>
         dbg = @dbg("connect")
         dbg()
+        if @_fatal
+            cb?('fatal')
+            return
         if @_state == 'closed'
             cb?('closed')
             return
@@ -289,14 +296,17 @@
                 # the client and server.   WORRY: when they sign in, things will not just start working again...
                 # but for now we need to defend ourselves.
                 dbg("FATAL error -- #{err}")
-                @close()
-                cb?("closed")
+                @_set_fatal(err)
+                cb?("fatal")
             else
                 cb?()
         )

     _reconnect: (cb) =>
         dbg = @dbg("_run")
+        if @_fatal
+            cb?('fatal')
+            return
         if @_state == 'closed'
             dbg("closed so don't do anything ever again")
             cb?()
@@ -318,6 +328,11 @@
                 if @_state == 'closed'
                     # already closed so ignore anything else.
                     cb?('closed')
+                    cb = undefined
+                    return
+
+                if @_fatal
+                    cb?('fatal')
                     cb = undefined
                     return

@@ -515,7 +530,7 @@
             @__save (err) =>
                 @__is_saving = false
                 if is_fatal(err)
-                    @_fatal = true
+                    @_set_fatal(err)
                 cb?(err)

     __save: (cb) =>
@@ -934,7 +949,27 @@

         return new_val

+    # If we get a fatal error, then we wait a bit.  This could happen due to being signed out,
+    # or thinking we're signed in, but not being signed in (since we *just* are in the process of
+    # being signed out).  It's rare, but there are dozens of tables, so even a 1% chance can
+    # easily happen.
+    _set_fatal: (why) =>
+        if @_fatal
+            return
+        tm = 10000 + Math.random()*20000
+        #console.log("_set_fatal", @_query, tm, why)
+        @_fatal = true
+        @_fatal_interval = setTimeout(@_unset_fatal, tm)
+
+    _unset_fatal: =>
+        #console.log("_unset_fatal", @_query)
+        delete @_fatal
+        delete @_fatal_interval
+
     close: =>
+        if @_fatal_interval
+            clearTimeout(@_fatal_interval)
+            delete @_fatal_interval
         if @_state == 'closed'
             # already closed
             return


Use correct syntax

Use correct syntax

--- src/coffee/stockimport.coffee
+++ src/coffee/stockimport.coffee
@@ -132,7 +132,7 @@
       header = data[0]
       @_getHeaderIndexes header, @csvHeaders
       .then (headerIndexes) =>
-        stocks = @_mapStockFromCSV data, headerIndexes[0], headerIndexes[1]
+        stocks = @_mapStockFromCSV _.tail(data), headerIndexes[0], headerIndexes[1]
         @logger.debug stocks, "Stock mapped from csv for indexes #{headerIndexes}"
         @_perform stocks, next
         .then (result) ->


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/collision_response.coffee
+++ src/collision_response.coffee
@@ -2,7 +2,7 @@
     # Handle multi-include
   self.unbind ".Movable"

-  self.bind 'update', (elapsedTime) ->
+  self.bind 'update.Movable', (elapsedTime) ->
     t = (elapsedTime * I.velocity.x).abs()
     unit = I.velocity.x.sign()


benchmark: mode to only create virtual browser

--- benchmarks/clients/client_process.coffee
+++ benchmarks/clients/client_process.coffee
@@ -276,14 +276,16 @@
                     # creating socket after children clients send initial requests
                     @emit('browserconfig', @browserConfig)
                 )
-
-            timers.setImmediate(()=>
-                @_createSocket()
-                @_initialSocketIo()
-            )
             logger("#{@id} opened #{@browserConfig.url}")

             @stats.add('initialPage', timeElapsed)
+            if not @options.createBrowserOnly
+                timers.setImmediate(()=>
+                    @_createSocket()
+                    @_initialSocketIo()
+                )
+            else
+                @stopped = true

     _initialSocketIo : ()->
         @_initStartTs()
@@ -525,6 +527,12 @@
         full : 'talkerCount'
         type : 'number'
         help : 'how many clients actually send events, by default it equals clientCount'
+    },
+    createBrowserOnly : {
+        env : 'CB_CREATEVBONLY'
+        default : false
+        type : 'boolean'
+        help : 'stop after the initial page loaded'
     }
 }


namespaced unbind

namespaced unbind

--- src/bindable.coffee
+++ src/bindable.coffee
@@ -93,7 +93,7 @@
         else
           eventCallbacks[event] = []
     else if namespace
-      eventCallbac
+      foreventCallbacks
         eventCallbacks[event] = eventCallbacks.select (callback) ->
           !callback.__PIXIE?[namespace]?


bind => on

bind => on

--- src/bindable.coffee
+++ src/bindable.coffee
@@ -25,7 +25,7 @@
   bind: ->
     self.on.apply(arguments)
   unbind: ->
-
+    self.off.apply(argumen)

   ###*
   Adds a function as an event listener.


Add error indicators to invalid fields in preset

--- client/app/views/register/preset.coffee
+++ client/app/views/register/preset.coffee
@@ -48,5 +48,17 @@
             password:    password
         req = Bacon.fromPromise $.post '/register', JSON.stringify data

-        @model.isRegistered.plug req.map(true)
-        @model.buttonBusy.plug req.mapEnd(false)
+        @model.isRegistered.plug req.map true
+        @model.buttonBusy.plug req.mapEnd false
+
+        errors = req.mapError '.responseJSON.error'
+           .map (message) ->
+                errors =
+                    email: /email/.test message
+                    timezone: /timezone/.test message
+
+        errors.map '.email'
+              .assign @ui.email.parent(), 'toggleClass', 'error'
+
+        errors.map '.timezone'
+              .assign @ui.timezone.parent(), 'toggleClass', 'error'


exponential backoff

exponential backoff

--- client/lanes/screens/Definitions.coffee
+++ client/lanes/screens/Definitions.coffee
@@ -95,7 +95,7 @@
                     resolve(me)
                 else if attempt < 3
                     attempt += 1
-                    _.delay(done, 500)
+                    _.delay(done, 500 * attempt)
                 else
                     reject("Screen #{me.view} not definied after file retrieval")
             err = (msg) ->


Removed debuggers

Removed debuggers

--- src/binding/binding.coffee
+++ src/binding/binding.coffee
@@ -62,7 +62,6 @@
       @value

   publish: =>
-    debugger
     if @observer
       value = @getValue @el

@@ -73,7 +72,6 @@
         if @view.formatters[id]?.publish
           value = @view.formatters[id].publish value, args...

-      debugger
       @observer.set value

   bind: =>


Fill all keys when transaction is executed, fill results with results from Gavel.validate

--- src/transaction-runner.coffee
+++ src/transaction-runner.coffee
@@ -173,35 +173,40 @@

           transaction['real'] = real

-          gavel.isValid real, transaction.expected, 'response', (error, isValid) ->
-            configuration.emitter.emit 'test error', error, test if error
+          gavel.isValid real, transaction.expected, 'response', (isValidError, isValid) ->
+            configuration.emitter.emit 'test error', isValidError, test if isValidError
+
+            test.start = test.start
+            test.title = transaction.id
+            test.actual = real
+            test.expected = transaction.expected
+            test.request = transaction.request

             if isValid
               test.status = "pass"
-              test.actual = real
-              test.expected = transaction.expected
-              test.request = transaction.request
-              configuration.emitter.emit 'test pass', test
+            else
+              test.status = "fail"
+
+            gavel.validate real, transaction.expected, 'response', (validateError, result) ->
+              if not isValidError and validateError
+                configuration.emitter.emit 'test error', validateError, test
+
+              message = ''
+
+              for resultKey, data of result
+                if resultKey isnt 'version'
+                  for entityResult in data['results']
+                    message += resultKey + ": " + entityResult['message'] + "\n"
+
+              test.message = message
+              test.results = result
+
+              if isValid
+                configuration.emitter.emit 'test pass', test
+              else
+                configuration.emitter.emit 'test fail', test
+
               return callback()
-            else
-              gavel.validate real, transaction.expected, 'response', (error, result) ->
-                configuration.emitter.emit 'test error', error, test if error
-                message = ''
-                delete result['version']
-                for entity, data of result
-                  for entityResult in data['results']
-                    message += entity + ": " + entityResult['message'] + "\n"
-
-                test.status = "fail"
-                test.title = transaction.id
-                test.message = message
-                test.actual = real
-                test.expected = transaction.expected
-                test.request = transaction.request
-                test.start = test.start
-                test.results = result
-                configuration.emitter.emit 'test fail', test
-                return callback()

       transport = if transaction.protocol is 'https:' then https else http
       try


Bind event with "once"

Bind event with "once"

--- client/account/lib/views/accountcredentiallistcontroller.coffee
+++ client/account/lib/views/accountcredentiallistcontroller.coffee
@@ -74,7 +74,7 @@
             listView.showCredentialEditModal { provider, credential, data }

-    @on 'FetchProcessSucceeded', (params) ->
+    @once 'FetchProcessSucceeded', (params) ->
       { items } = params
       if provider and items?.length is 0
         @showAddCredentialFormFor provider


More meaningful label for time tracking

More meaningful label for time tracking

--- client/landing/app/MainApp/maincontroller/maincontroller.coffee
+++ client/landing/app/MainApp/maincontroller/maincontroller.coffee
@@ -57,7 +57,8 @@
       KD.registerSingleton "kodingAppsController",    new KodingAppsController
       @showInstructionsBookIfNeeded()
       @emit 'AppIsReady'
-      console.timeEnd "KDA"
+
+      console.timeEnd "Koding.com loaded"

   accountChanged:(account, firstLoad = no)->
     @userAccount             = account


adding definition of paramorhism

adding definition of paramorhism

--- scripts/morphism.coffee
+++ scripts/morphism.coffee
@@ -50,7 +50,7 @@
     msg.send ""

   robot.respond /define paramorphism/i, (msg)->
-    msg.send ""
+    msg.send "It is a more convenient version of `catamorphism` in that it gives the combining step function immediate access not only to the result value recursively computed from each recursive subobject, but the original subobject itself as well."

   robot.respond /define polymorphism/i, (msg)->
     msg.send "One that have multiple morphism."


Rm log

Rm log

--- components/blocks/container/client/block_collection_view.coffee
+++ components/blocks/container/client/block_collection_view.coffee
@@ -98,7 +98,6 @@
         el: $block

   setupNewBlockView: ({ channel, autoRender =  false }) ->
-    console.log 'setupNewBlockView autoRender', autoRender
     @newBlockView = new @newBlockViews[@state.get('view_mode')]
       el: $('.block-item--new')
       blocks: @collection


defining operations

defining operations

--- js/Formals/Expression.coffee
+++ js/Formals/Expression.coffee
@@ -14,6 +14,7 @@
     @parse = @fromString

     @parser = new mathJS.Algorithms.ShuntingYard(
+    # TODO: use operations from operation class
         "^":
             precedence: 4
             associativity: "right"