Reorder expects to see the mapping better.

--- src/spec/stockxmlimport.spec.coffee
+++ src/spec/stockxmlimport.spec.coffee
@@ -82,8 +82,8 @@
       expect(s.expectedDelivery).toBe '2013-11-19T00:00:00'
       s = stocks[1]
       expect(s.sku).toBe 'foo-bar'
+      expect(s.quantityOnStock).toBe 12
+      expect(s.expectedDelivery).toBe '2013-11-05T00:00:00'
       expect(s.supplyChannel.typeId).toBe 'channel'
       expect(s.supplyChannel.id).toBe 'myChannelId'
-      expect(s.quantityOnStock).toBe 12
-      expect(s.expectedDelivery).toBe '2013-11-05T00:00:00'
       done()


Fixed download overlay

Fixed download overlay

--- static/js/dss/lib/peneloPlay.coffee
+++ static/js/dss/lib/peneloPlay.coffee
@@ -94,7 +94,7 @@
             top: ui.waveform.position().top
             left: (ui.waveform.position().left + ui.waveform.width()) - ui.timeDuration.width()

-        if soundManager.html5.mp3
+        if false #soundManager.html5.mp3
             ui.downloadOverlay.hide()
         else
             ui.downloadOverlay.animate


correctly set cursor for format undos

correctly set cursor for format undos

--- src/undo-manager.coffee
+++ src/undo-manager.coffee
@@ -5,13 +5,18 @@
 getLastChangeIndex = (delta) ->
   lastChangeIndex = index = offset = 0
   _.each(delta.ops, (op) ->
+    # Insert
     if Tandem.Delta.isInsert(op)
       offset += op.getLength()
       lastChangeIndex = index + offset
     else if Tandem.Delta.isRetain(op)
+      # Delete
       if op.start > index
         lastChangeIndex = index + offset
         offset -= (op.start - index)
+      # Format
+      if _.keys(op.attributes).length > 0
+        lastChangeIndex = op.end + offset
       index = op.end
   )
   if delta.endLength < delta.startLength + offset


Fixed typo

Fixed typo

--- src/transaction-runner.coffee
+++ src/transaction-runner.coffee
@@ -490,7 +490,7 @@
                 if beforeResults?
                   transaction['results'][key]['results'] = transaction['results'][key]['results'].concat beforeResults

-              test['results'] = transaction.['results']
+              test['results'] = transaction['results']

               test['valid'] = isValid


Use optionNode.text instead of innerHTML to correctly update option texts in all browsers.

--- src/view/dom/dom.coffee
+++ src/view/dom/dom.coffee
@@ -99,6 +99,8 @@
         if isSetting then (node.value = value) else node.value
       when 'SELECT'
         if isSetting then node.value = value
+      when 'OPTION'
+        if isSetting then node.text = value else node.text
       else
         if isSetting
           Batman.DOM.setInnerHTML node, if escapeValue then Batman.escapeHTML(value) else value


menus: Change "Report a problem" notification text

--- src/js/menus.coffee
+++ src/js/menus.coffee
@@ -652,7 +652,7 @@
                 body: "Please send an email to #{config.SUPPORT_EMAIL}
                        including the following ID:\n\
                        #{accountToken}\n\
-                       (You can take a screenshot of this screen)"
+                       (Just take a photo)"
               ).show()
             (err, status, request) ->
               changeSubtitleGivenEvent "", e


show last 100 tracks

show last 100 tracks


Ugly quick fix for empty tagclouds

Ugly quick fix for empty tagclouds

--- static/js/member.coffee
+++ static/js/member.coffee
@@ -48,7 +48,10 @@

 tags = ({name: x[0], count: x[1], url: '#'} for x in keyword_activity)
 tags = _.sortBy tags, (x) -> x.name
-$("#member-tag-cloud").tag_cloud tags
+if tags.length > 0
+    $("#member-tag-cloud").tag_cloud tags
+else
+    $("#member-tag-cloud").append("
Ei asiasanoitettua aktiivisuutta
")

 feed_view = new MemberActivityFeedView member


removed uneeded dependency from multi validator

--- lib/multi_validator.coffee
+++ lib/multi_validator.coffee
@@ -1,6 +1,5 @@
 _ = require('lodash')

-FieldValidator = require('./field_validator.coffee')
 ValidationError = require('./error.coffee')

 module.exports = class MultiValidator


Fix ternary operator and parameter passing

--- lib/package-manager.coffee
+++ lib/package-manager.coffee
@@ -223,7 +223,8 @@
   # eventName - The event name suffix {String} of the event to emit.
   # pack - The package for which the event is being emitted.
   # error - Any error information to be included in the case of an error.
-  emitPackageEvent: (eventName, {theme}, error) ->
+  emitPackageEvent: (eventName, pack, error) ->
+    {theme} = pack
     theme ?= pack.metadata?.theme
-    eventName = theme ? "theme-#{eventName}" : "package-#{eventName}"
+    eventName = if theme then "theme-#{eventName}" else "package-#{eventName}"
     @emit eventName, pack, error


* [test] nosql-subkey sort genData for FakeIterator is sorted.

--- test/nosql-subkey-test.coffee
+++ test/nosql-subkey-test.coffee
@@ -52,6 +52,19 @@
     valueEncoding = db.valueEncoding _opts
     value = if valueEncoding then valueEncoding.encode(item.value) else item.value
     db.data.should.have.property key, value
+  _opts = {}
+  data.sort (a,b)->
+    _opts.keyEncoding = a.keyEncoding
+    _opts.keyEncoding = opts.keyEncoding if opts and not _opts.keyEncoding
+    keyEncoding = db.keyEncoding _opts
+    a = if keyEncoding then keyEncoding.encode a.key else a.key
+    _opts.keyEncoding = b.keyEncoding
+    _opts.keyEncoding = opts.keyEncoding if opts and not _opts.keyEncoding
+    keyEncoding = db.keyEncoding _opts
+    b = if keyEncoding then keyEncoding.encode b.key else b.key
+    return 1 if a > b
+    return -1 if a < b
+    return 0
   data

 getEncodedKey = (db, key, options, parentPath) ->


Set orientation to stop misalignment issues


Code formatting.

Code formatting.

--- app/client/js/react/pages/editsong.coffee
+++ app/client/js/react/pages/editsong.coffee
@@ -57,7 +57,8 @@
                 placeholder: EditSong.MSG_WRITE_LYRICS_HERE
                 ref: 'lyrics'
                 value: song.lyrics
-              @renderLocalHistory song
+              userStore.isLogged() &&
+                @renderLocalHistory song
               p className: 'help-block',
                 a
                   href: 'http://linkesoft.com/songbook/chordproformat.html'
@@ -79,7 +80,8 @@

       renderLocalHistory: (song) ->
         lyricsHistory = @getLyricsHistory song
-        if previousLyricsHistory && lyricsHistory
+
+        if previousLyricsHistory
           lyricsHistoryChanged = previousLyricsHistory.join() != lyricsHistory.join()
         previousLyricsHistory = lyricsHistory

@@ -95,9 +97,10 @@
             onPointerUp: @onLyricsHistoryBtnPointerUp
             type: 'button'
           , EditSong.MSG_LYRICS_HISTORY
-          lyricsHistoryShown && div {},
-            ol {}, lyrics
-            p {}, EditSong.MSG_LYRICS_HISTORY_P
+          lyricsHistoryShown &&
+            div {},
+              ol {}, lyrics
+              p {}, EditSong.MSG_LYRICS_HISTORY_P

       onLyricsHistoryBtnPointerUp: ->
         lyricsHistoryShown = !lyricsHistoryShown


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/flickerable.coffee
+++ test/flickerable.coffee
@@ -29,7 +29,8 @@
     equals player.I.alpha, 0.2

   5.times ->
-    player.up
+    player.update()
+    equals player.I.alpha

 module()


add test for getAssembly partial response

--- test/integration.coffee
+++ test/integration.coffee
@@ -82,6 +82,29 @@
           expect(result.assembly_id).to.equal id
           done()

+    it "should get a full assembly status reliably", (done) ->
+      @timeout 0
+
+      client = new TransloaditClient { authKey, authSecret }
+
+      reproduce = (nattempts) ->
+        if nattempts == 0
+          return done()
+
+        client.createAssembly genericParams, (err, result) ->
+          if err? || result.error?
+            return reproduce nattempts - 1
+
+          client.getAssembly result.assembly_id, (err, result) ->
+            if err? || result.error?
+              return reproduce nattempts - 1
+
+            expect(result).to.have.property("assmembly_url").that.exist
+            reproduce nattempts - 1
+
+      # attempt to reproduce the incomplete status response 100 times
+      reproduce 100
+
   describe "assembly cancelation", ->
     it "should stop the assembly from reaching completion", (done) ->
       client = new TransloaditClient { authKey, authSecret }


add test for b-repeat

add test for b-repeat

--- test/render-test.coffee
+++ test/render-test.coffee
@@ -90,33 +90,87 @@
         assert.deepEqual rendered, @expected

   context 'b-repeat', ->
-    beforeEach ->
-      @parsed = [
-        name: 'p'
-        attributes: [
-          name: 'b-repeat'
-          value: 'item in list'
+    context 'simple', ->
+      beforeEach ->
+        @parsed = [
+          name: 'p'
+          attributes: [
+            name: 'b-repeat'
+            value: 'item in list'
+          ,
+            name: 'b-html'
+            value: 'item'
+          ]
+          children: []
+        ]
+        @context =
+          list: [
+            'item1'
+            'item2'
+          ]
+        @expected = [
+          name: 'p'
+          attributes: []
+          children: ['item1']
         ,
-          name: 'b-html'
-          value: 'item'
+          name: 'p'
+          attributes: []
+          children: ['item2']
         ]
-        children: []
-      ]
-      @context =
-        list: [
-          'item1'
-          'item2'
+
+      it 'works', ->
+        rendered = render @parsed, @context
+        assert.deepEqual rendered, @expected
+
+    context 'complex', ->
+      beforeEach ->
+        @parsed = [
+          name: 'ul'
+          attributes: []
+          children: [
+            name: 'li'
+            attributes: [
+              name: 'b-repeat'
+              value: 'user in users'
+            ]
+            children: [
+              name: 'span'
+              attributes: [
+                name: 'b-html'
+                value: 'user.name'
+              ]
+              children: []
+            ]
+          ]
         ]
-      @expected = [
-        name: 'p'
-        attributes: []
-        children: ['item1']
-      ,
-        name: 'p'
-        attributes: []
-        children: ['item2']
-      ]
+        @context =
+          users: [
+            name: 'bouzuya'
+          ,
+            name: 'emanon001'
+          ]
+        @expected = [
+          name: 'ul'
+          attributes: []
+          children: [
+            name: 'li'
+            attributes: []
+            children: [
+              name: 'span'
+              attributes: []
+              children: ['bouzuya']
+            ]
+          ,
+            name: 'li'
+            attributes: []
+            children: [
+              name: 'span'
+              attributes: []
+              children: ['emanon001']
+            ]
+          ]
+        ]

-    it 'works', ->
-      rendered = render @parsed, @context
-      assert.deepEqual rendered, @expected
+      it 'works', ->
+        rendered = render @parsed, @context
+        assert.deepEqual rendered, @expected


use event stream to update document

use event stream to update document

--- src/notebook.coffee
+++ src/notebook.coffee
@@ -3,7 +3,7 @@
   _ = require 'underscore'
   CodeMirror = require 'cm/codemirror'
   URI = require 'URIjs'
-  Bacon = require 'baconjs'
+  Bacon = require 'bacon.model'
   Editor = require 'editor'
   http = require 'http'
   graphite = require 'graphite'
@@ -51,6 +51,8 @@
     DocumentComponent = React.createClass
       displayName: 'DocumentComponent'
       mixins: [React.ComponentListMixin]
+      getInitialState: ->
+        unsubscribe: @props.cells_model.onValue @set_cells
       render: ->
         React.DOM.div {className: 'document'}, @state.components
       # FIXME #163 can't call this
@@ -68,10 +70,12 @@
         # reset the file picker so change is triggered again
         $file_picker.val ''

-      document = DocumentComponent()
+      cells_model = Bacon.Model([])
+      document = DocumentComponent {cells_model}
       # FIXME add file picker
       notebook =
         cells: []
+        cells_model: cells_model
         input_number: 1
         output_number: 1
         component: document
@@ -106,8 +110,7 @@
       notebook

     update_view = (notebook) ->
-      # FIXME #163 can't call methods on component specs
-      notebook.component.set_cells notebook.cells
+      notebook.cells_model.set notebook.cells.slice()

     clear_notebook = (notebook) ->
       for cell in notebook.cells


adding max line length

adding max line length

--- lib/CoffeeJs.coffee
+++ lib/CoffeeJs.coffee
@@ -45,7 +45,7 @@
     @B = browserify({debug: @debug, extensions: ['.coffee']})
     #@B.transform(Base64.transform)
     @B.transform(coffeeify, {sourceMap: true})
-    @B.transform(uglifyify, { global: true  })
+    @B.transform(uglifyify, { global: true, 'max-line-len': 150000 })
     @B.add(@source)

     @B.on('file', (file, id, parent)=>


updating coffee transform to apply globally

--- lib/CoffeeJs.coffee
+++ lib/CoffeeJs.coffee
@@ -44,7 +44,7 @@

     @B = browserify({debug: @debug, extensions: ['.coffee']})
     #@B.transform(Base64.transform)
-    @B.transform(coffeeify, {sourceMap: true})
+    @B.transform(coffeeify, {sourceMap: true, global: true})
     @B.transform(uglifyify, { global: true, max_line_len: 150000 }) if @uglifyify
     @B.add(@source)


Shows might not have artworks

Shows might not have artworks

--- models/partner_show.coffee
+++ models/partner_show.coffee
@@ -57,7 +57,7 @@

     # if not, try the image of its first artwork, if we already have some
     size = 'larger' if featured
-    if @artworks?.length > 0
+    if @artworks?.length
       return @artworks.first().defaultImage().imageUrl size

     # if not, fetch some artworks and use one of their images
@@ -67,8 +67,9 @@
       url     : "#{@url()}/artworks"
       cache   : true
       success : =>
-        imageUrl = @artworks.first().defaultImage().imageUrl size
-        @trigger "fetch:posterImageUrl", imageUrl
+        if @artworks?.length
+          imageUrl = @artworks.first().defaultImage().imageUrl size
+          @trigger "fetch:posterImageUrl", imageUrl
     @artworks.fetch options
     false


Cleaning up and clarifying a TODO regarding redisClient

--- lib/content._coffee
+++ lib/content._coffee
@@ -21,8 +21,7 @@
 # TEMP: Simple implementation for just two data stores: Redis and flat files.
 USE_REDIS = config.DATA_STORE is 'redis'

-# TODO: We should only instantiate this if we're using Redis, but we currently
-# do rely on Redis for the "next ID" (see above), even in the flat file case.
+# TODO: Make the !USE_REDIS behavior more robust than just not creating a client
 # TODO: We should also support auth'ed Redis, which is an async connection.
 redisClient = redis.createClient() if USE_REDIS


oopsy

oopsy

--- lib/devunity.coffee
+++ lib/devunity.coffee
@@ -101,15 +101,15 @@
         success: (response) =>
           if response
             @confirm(response.url,response.username)
-    else
-      atom.confirm(
-        {
-          'message':'You\'re not logged in :/',
-          'detailedMessage':'In order to use devunity you need to set your API key in the plugin settings screen',
-          'buttons':
-            {'good':'test','bad':'test'}
-        }
-      );
+    #else
+    #  atom.confirm(
+    #    {
+    #      'message':'You\'re not logged in :/',
+    #      'detailedMessage':'In order to use devunity you need to set your API key in the plugin settings screen',
+    #      'buttons':
+    #        {'good':'test','bad':'test'}
+    #    }
+    #  );

   confirm: (codeurl,username) ->


Show server-side members

Show server-side members


don't calculate absolute value twice in hard shading mode

--- oriDomi.coffee
+++ oriDomi.coffee
@@ -376,10 +376,11 @@

   _setShader: (i, anchor, angle) ->
-    opacity = Math.abs(angle) / 90 * @shadingIntensity * .3
+    abs = Math.abs angle
+    opacity = abs / 90 * @shadingIntensity * .3

     if @settings.hardShading
-      angle = Math.abs angle
+      angle = abs

     switch anchor
       when 'left', 'top'


pass touch event objects to callbacks

pass touch event objects to callbacks

--- oridomi.coffee
+++ oridomi.coffee
@@ -786,7 +786,7 @@
       @[axis1] = e.targetTouches[0]["page#{ @_touchAxis.toUpperCase() }"]

     # Return that value to an external listener.
-    @_settings.touchStartCallback @[axis1]
+    @_settings.touchStartCallback @[axis1], e

   # Called on touch/mouse movement.
@@ -818,15 +818,14 @@
       delta = 0 if delta < 0

-    delta = @_normalizeAngle delta
-    @_lastOp.angle = delta
+    @_lastOp.angle = delta = @_normalizeAngle delta
     @_lastOp.fn.call @, delta, @_lastOp.anchor, @_lastOp.options
-    @_settings.touchMoveCallback delta
+    @_settings.touchMoveCallback delta, e

   # Teardown process when touch/drag event ends.
-  _onTouchEnd: =>
+  _onTouchEnd: (e) =>
     return unless @_touchEnabled
     # Restore the initial touch status and cursor.
     @_touchStarted = @_inTrans = false
@@ -834,19 +833,19 @@
     # Enable tweening again.
     @_setTrans @_settings.speed, @_settings.ripple
     # Pass callback final value.
-    @_settings.touchEndCallback @["_#{ @_touchAxis }Last"]
+    @_settings.touchEndCallback @["_#{ @_touchAxis }Last"], e

   # End folding when the mouse or finger leaves the composition.
-  _onTouchLeave: =>
+  _onTouchLeave: (e) =>
     return unless @_touchEnabled and @_touchStarted
-    @_onTouchEnd()
+    @_onTouchEnd e

   # A fallback for browsers that don't support `mouseleave`.
   _onMouseOut: (e) =>
     return unless @_touchEnabled and @_touchStarted
-    @_onTouchEnd() if e.toElement and !@el.contains e.toElement
+    @_onTouchEnd e if e.toElement and !@el.contains e.toElement

   _unfold: (callback) ->


clarity in jquery bridge

clarity in jquery bridge

--- oridomi.coffee
+++ oridomi.coffee
@@ -1220,8 +1220,7 @@
       for el in @
         # If the element in the selection already has an instance of oriDomi
         # attached to it, return the instance.
-        instance = $.data el, 'oriDomi'
-        if instance
+        if instance = $.data el, 'oriDomi'
           return instance
         else
           # Create an instance of oriDomi and attach it to the element.


fixed up unfreeze()

fixed up unfreeze()

--- oridomi.coffee
+++ oridomi.coffee
@@ -838,9 +838,9 @@
       @isFrozen = false
       # Swap the visibility of the elements.
       @cleanEl.style[css.transform] = 'translate3d(-9999px, 0, 0)'
-      @stageHolder.style[css.transform] = 'translate3d(0, 0, 0)'
+      @stageHolder.style[css.transform] = 'translateY(-100%)'
       # Set `lastAngle` to 0 so an immediately subsequent call to `freeze` triggers the callback.
-      @lastAngle = 0
+      @lastOp.angle = 0

   # Removes the oriDomi element and marks its instance for garbage collection.


Change PathWatcher.close() to PathWatcher.closeAllWatchers() # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Your branch is ahead of 'origin/master' by 3 commits. #   (use "git push" to publish your local commits) # # Changes to be committed: #   (use "git reset HEAD <file>..." to unstage) # # 	modified:   lib/git-plus.coffee # #

--- lib/git-plus.coffee
+++ lib/git-plus.coffee
@@ -56,7 +56,7 @@
       options:
         cwd: @dir
       stdout: (data) =>
-        PathWatcher.close()
+        PathWatcher.closeAllWatchers()
         atom.workspace.destroyActivePane()
       stderror: (data) =>
         alert data.toString()


fix copy paste error

fix copy paste error

--- lib/grammars.coffee
+++ lib/grammars.coffee
@@ -156,10 +156,10 @@
   ioLanguage:
     "Selection Based":
       command: "io"
-      args: (context) -> [context.filepath]
+      args: (context) -> [context.getCode()]
     "File Based":
       command: "io"
-      args: (context) -> ['-e', context.getCode()]
+      args: (context) -> ['-e', context.filepath]

   Java:
     "File Based":


Add limit rule for createDirectMessage method

--- server/methods/createDirectMessage.coffee
+++ server/methods/createDirectMessage.coffee
@@ -70,3 +70,9 @@
 		return {
 			rid: rid
 		}
+
+DDPRateLimiter.addRule
+	type: 'method'
+	name: 'createDirectMessage'
+	connectionId: -> return true
+, 10, 60000


allow external stylesheet url

allow external stylesheet url

--- src/renderer.coffee
+++ src/renderer.coffee
@@ -83,6 +83,7 @@
     this.addStyles(DEFAULT_STYLES)
     # Ensure user specified styles are added after modules'
     _.defer(_.bind(this.addStyles, this, @options.styles)) if @options.styles?
+    _.defer(_.bind(this.addStyles, this, @options.stylesheet)) if @options.stylesheet?

   addContainer: (className, before = false) ->
     refNode = if before then @root else null
@@ -92,11 +93,20 @@
     return container

   addStyles: (css) ->
-    style = @root.ownerDocument.createElement('style')
-    style.type = 'text/css'
-    css = Renderer.objToCss(css)
-    style.appendChild(@root.ownerDocument.createTextNode(css))
-    @root.ownerDocument.head.appendChild(style)
-
-
+    if typeof css == 'object'
+      style = @root.ownerDocument.createElement('style')
+      style.type = 'text/css'
+      css = Renderer.objToCss(css)
+      style.appendChild(@root.ownerDocument.createTextNode(css))
+      @root.ownerDocument.head.appendChild(style)
+    else if typeof css == 'string'
+      # external stylesheet
+      link = @root.ownerDocument.createElement('link')
+      DOM.setAttributes(link,
+        type: 'text/css'
+        rel: 'stylesheet'
+        href: css
+      )
+      @root.ownerDocument.head.appendChild(link)
+
 module.exports = Renderer


Uses markdown.js to convert to HTML

Uses markdown.js to convert to HTML

--- lib/markdown.coffee
+++ lib/markdown.coffee
@@ -1,13 +1,15 @@
-Showdown = require 'showdown'
-converter = new Showdown.converter()
+markdown = require('markdown').markdown
+
+stripTags = (str) ->
+  return '' unless str?
+  String(str).replace(/<\/?[^>]+>/g, '')

 module.exports =
-
   mdToHtml: (attr) ->
-    converter.makeHtml @get(attr) or ''
+    markdown.toHTML @get(attr) or ''

   mdToHtmlToText: (attr) ->
-    @mdToHtml(attr).replace(/<(?:.|\n)*?>/gm, '')
+    stripTags(@mdToHtml attr)

   htmlToText: (attr) ->
-    @get(attr).replace(/<(?:.|\n)*?>/gm, '')+    stripTags(@get attr)


Avoid doing $max on dates in client simulation

--- lib/messages.coffee
+++ lib/messages.coffee
@@ -627,7 +627,7 @@
   #_submessagesChanged old.root ? id
   ## In this special case, we can efficiently simulate the behavior of
   ## _submessagesChanged via a direct update to the root:
-  if _consideredSubmessage message, old
+  if Meteor.isServer and _consideredSubmessage message, old
     rootUpdate = $max: submessageLastUpdate: message.updated
     if old.root? and not _consideredSubmessage old
       rootUpdate.$inc = submessageCount: 1  ## considered a new submessage
@@ -861,7 +861,7 @@
       #_submessagesChanged message.root
       ## In fact, in this special case, we can efficiently simulate the
       ## behavior of _submessagesChanged via a direct update to the root:
-      if _consideredSubmessage message
+      if Meteor.isServer and _consideredSubmessage message
         Messages.update message.root,
           $inc: submessageCount: 1
           $max: submessageLastUpdate: message.updated


Removed old prefix function

Removed old prefix function

--- lib/provider.coffee
+++ lib/provider.coffee
@@ -146,20 +146,6 @@
     catch error
       console.error error

-  ###
-  This is a lightly modified version of AutocompleteManager.prefixForCursor
-  which allows autocomplete-bibtex to define its own wordRegex.
-
-  N.B. Setting `allowPrevious` to `false` is absolutely essential in order to
-  make this perform as expected.
-  ###
-  prefixForCursor: (cursor, buffer) =>
-    return '' unless buffer? and cursor?
-    start = cursor.getBeginningOfCurrentWordBufferPosition({ wordRegex: @wordRegex, allowPrevious: false })
-    end = cursor.getBufferPosition()
-    return '' unless start? and end?
-    buffer.getTextInRange([start, end])
-
   prettifyTitle: (title) ->
     return if not title
     if (colon = title.indexOf(':')) isnt -1 and title.split(" ").length > 5


:racehorse: Defer request require until exception is sent

--- lib/reporter.coffee
+++ lib/reporter.coffee
@@ -1,4 +1,4 @@
-request = require 'request'
+request = null # Defer require until error is actually sent

 module.exports =
 class Reporter
@@ -10,6 +10,7 @@
       body: JSON.stringify(@buildParams(message, url, line))

   @request: (options) ->
+    request ?= require 'request'
     request options, -> # Callback prevents errors from going to the console

   # Private:


Fix --tex generation in combination with unrecognized symbols

`unrecognizedSymbol` wasn't working with `--tex` conversion

--- src/svgtiler.coffee
+++ src/svgtiler.coffee
@@ -2101,6 +2101,7 @@
       for tiles, j in row
         for tile, k in tiles
           {xMin, yMin} = tile
+          continue unless tile.symbol.text?  # e.g. unrecognizedSymbol
           for text in tile.symbol.text
             tx = parseNum(text.getAttribute('x')) ? 0
             ty = parseNum(text.getAttribute('y')) ? 0


Use self instead of @

Use self instead of @

--- src/telegram.coffee
+++ src/telegram.coffee
@@ -246,7 +246,7 @@
                     else
                         for msg in result
                             # Increment the current offset
-                            @offset = msg.update_id
+                            self.offset = msg.update_id

                         for msg in result
                             self.handleUpdate msg


borrowed _.type mixin (to use instead of typeof)

--- lib/undermix.coffee
+++ lib/undermix.coffee
@@ -1,7 +1,20 @@
-# define (require, exports, module) ->
+# TODO: define (require, exports, module) ->
 _ =     require("underscore")
 _.mixin require("underscore.string")
 _.mixin
+
+  # Borrowed [type function](http://coffeescriptcookbook.com/chapters/classes_and_objects/type-function)
+  # to use instead of the [typeof operator](https://developer.mozilla.org/en/JavaScript/Reference/Operators/typeof)
+  type: (obj) ->
+    if obj == undefined or obj == null
+      return String obj
+    classToType = new Object
+    for name in "Boolean Number String Function Array Date RegExp".split(" ")
+      classToType["[object " + name + "]"] = name.toLowerCase()
+    myClass = Object.prototype.toString.call obj
+    if myClass of classToType
+      return classToType[myClass]
+    return "object"

   # Converts the arguments list to an Array
   aToArr: (list) ->


Added isFloat().

Added isFloat().

--- src/Numbers.coffee
+++ src/Numbers.coffee
@@ -1,3 +1,5 @@
 Numbers =

   isDefined: (value) -> value != '' && value? && !isNaN(value)
+
+  isFloat: (value) -> value? && value.toString().indexOf('.') >= 0


Store node in ~/.atom/.node-gyp

Store node in ~/.atom/.node-gyp

--- src/apm-cli.coffee
+++ src/apm-cli.coffee
@@ -24,7 +24,8 @@
 install = (options) ->
   nodeVersion = '0.10.3'
   nodeUrl = 'https://gh-contractor-zcbenz.s3.amazonaws.com/cefode2/dist'
-  nodeDirectory = "#{process.env['HOME']}/.cefode-gyp"
+  atomDirectory = "#{process.env.HOME}/.atom"
+  nodeDirectory = "#{atomDirectory}/.node-gyp"

   commands = []
   commands.push (callback) ->


cleaner: Add assembly output folder deletion to ultraclean option

--- src/cleaner.coffee
+++ src/cleaner.coffee
@@ -1,7 +1,7 @@
 { attemptShell, isBinaryExecutable , hasProgramInstalled} = require './utils'
 logger = require './logger'
 styler = require './styler'
-{ PROFILING_OUTPUT_FOLDER } = require './constants'
+{ PROFILING_OUTPUT_FOLDER, ASSEMBLY_OUTPUT_FOLDER } = require './constants'
 _ = require 'lodash'

 @clean = ({ recursive = no, ultraDeep = no, deep = ultraDeep, } = {}) ->
@@ -23,7 +23,7 @@
                 file.match(/\.out$/) or
                 file is "oprofile_data" or
                 (ultraDeep and (
-                    file is PROFILING_OUTPUT_FOLDER
+                    file in [PROFILING_OUTPUT_FOLDER, ASSEMBLY_OUTPUT_FOLDER]
                 ))
         else
             isBinaryExecutable


Add error checking after calling docker.buildImage

--- src/decking.coffee
+++ src/decking.coffee
@@ -342,7 +342,8 @@

       log "Uploading tarball..."
       docker.buildImage tarball, options, (err, res) ->
-
+        return done err if err
+
         res.pipe process.stdout

         res.on "end", ->


applyForces calls setVelocity.

applyForces calls setVelocity.

--- src/element.coffee
+++ src/element.coffee
@@ -42,15 +42,16 @@
     getVelocity : () ->
         return @direction.normalize().scale(@speed)

+    # Set the element's velocity.
+    setVelocity : (velocity) ->
+        @speed = velocity.getLength()
+        @direction = velocity.normalize() unless velocity.isZeroVector()
+
     # Apply an impulse force to the element.
     applyImpulse : (impulse) ->
         return this if @isStatic()
         velocity = @getVelocity().add(impulse)
         @setVelocity(velocity)
-
-    setVelocity : (velocity) ->
-        @direction = velocity.normalize()
-        @speed = velocity.getLength()

     # Apply the given force to the element for the given number of
     # milliseconds.
@@ -65,8 +66,7 @@

         # Update the element's state.
         @setPosition(position)
-        @speed = velocity.getLength()
-        @direction = velocity.normalize() unless velocity.isZeroVector()
+        @setVelocity(velocity)

     # Return true if this element intersects with the other
     # element, false otherwise.


Fix file watching.

Fix file watching.

--- src/helpers.coffee
+++ src/helpers.coffee
@@ -170,7 +170,7 @@
     # Prevent memory leaks.
     return if basename in parent
     parent.push basename
-    fs.watch item, persistent: yes, interval: 500, (curr, prev) =>
+    fs.watchFile item, persistent: yes, interval: 500, (curr, prev) =>
       callback? item unless curr.mtime.getTime() is prev.mtime.getTime()

   _handleFile: (file) ->
@@ -211,7 +211,6 @@

   # Removes all listeners from watched files.
   clear: ->
-    @removeAllListeners 'change'
     for directory, files of @watched
       for file in files
         fs.unwatchFile path.join directory, file


Fixed crash when not all defined object keys are available in the device object parameter.

--- presets.coffee
+++ presets.coffee
@@ -16,6 +16,7 @@
 matchObject = (object, param) ->
   return false if not object._keys? or object._keys.length == 0
   for k in object._keys
+    return false if not param[k]?
     v = common.matchType(param[k]._value, object[k])
     if param[k]._value != v
       return false


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/metered.coffee
+++ src/metered.coffee
@@ -95,7 +95,7 @@
           color: borderColor
           width: 1.5

-###*
+  ###*
   The position of this game object. By default it is the top left point.
   Redefining the center method will change the relative position.


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/metered.coffee
+++ src/metered.coffee
@@ -173,7 +173,7 @@
   player.meter 'health'
     show: false

-  # enabl
+  # enables visibility for the 'health' meter
   player.showMeter 'health'
   </pre></code>


Rename Meter module

Rename Meter module

--- src/metered.coffee
+++ src/metered.coffee
@@ -30,7 +30,7 @@
 @param {GameObject} self Reference to including object
 ###

-Metered = (I={}, self) ->
+GameObject.Metered = (I={}, self) ->
   Object.reverseMerge I,
     meters: {}


The LineNumberTable may not be the first attribute.

javac seems to output classfiles with that ordering, but JRuby doesn't.

--- src/natives.coffee
+++ src/natives.coffee
@@ -224,11 +224,12 @@
         source_file = 'Native Method'
       else
         source_file = cls.get_attribute('SourceFile')?.filename or 'unknown'
-        line_nums = sf.method.code?.attrs?[0]?.entries
-        if line_nums?
+        break unless attrs = sf.method.code?.attrs?
+        for attr in attrs when a.name is 'LineNumberTable'
           # get the last line number before the stack frame's pc
-          for i,row of line_nums when row.start_pc <= sf.pc
+          for i,row of attr when row.start_pc <= sf.pc
             ln = row.line_number
+          break
     else
       source_file = 'unknown'
     stacktrace.push new JavaObject rs, rs.get_bs_class('Ljava/lang/StackTraceElement;'), {


tweak default font

tweak default font

--- src/nvim/ui.coffee
+++ src/nvim/ui.coffee
@@ -109,7 +109,7 @@
     @resize_timer = null

   init_font: ->
-    @font = '13px monospace'
+    @font = '13px Inconsolata, Monaco, Consolas, \'Source Code Pro\', \'Ubuntu Mono\', \'DejaVu Sans Mono\', \'Courier New\', Courier, monospace'
     @font_test_node.style.font = @font
     @font_test_node.innerHTML = 'm'


Remove unused instance variable

Remove unused instance variable

Signed-off-by: Jessica Lord <7acbd1498e1be10a1338a61df68672fe4daf35c1@github.com>

--- src/project.coffee
+++ src/project.coffee
@@ -165,7 +165,6 @@
   setPaths: (projectPaths) ->
     [projectPath] = projectPaths
     projectPath = path.normalize(projectPath) if projectPath
-    @path = projectPath
     @rootDirectory?.off()

     @destroyRepo()


At least one participant

At least one participant

--- app/controllers/home_page.coffee
+++ app/controllers/home_page.coffee
@@ -4,7 +4,7 @@
 FILMING = true

 FROM_BEFORE_BBC =
-  user_count: 11858
+  user_count: 11857
   classification_count: 10921085

 class HomePage extends Page


fix local module dependency -

fix local module dependency
-

--- src/request.coffee
+++ src/request.coffee
@@ -3,7 +3,7 @@
 { Duplex } = require 'stream'

 _ = require 'lodash'
-Multisource = require '../../multisource-stream'
+Multisource = require 'multisource-stream'

 Thread = require './thread'


disable ace workers

disable ace workers

--- src/require.coffee
+++ src/require.coffee
@@ -114,3 +114,6 @@
 this.require.resolve   = resolve
 this.require.nameToUrl = (path) -> "#{path}.js"
 this.require.__modules = __modules
+
+# issue #17
+this.require.noWorker = true


runtime: Also send runtime UUID in live URL

--- src/runtime.coffee
+++ src/runtime.coffee
@@ -120,7 +120,7 @@
     address = scheme + @options.host + ':' + @options.port

   liveUrl: () ->
-    params = querystring.escape "protocol=websocket&address=#{@address()}"
+    params = querystring.escape "protocol=websocket&address=#{@address()}&id=#{@options.runtimeId}"
     url = "#{@options.ide}#runtime/endpoint?#{params}"

   serveFrontpage: (req, res) ->


Fix prev method when repeat is on

Fix prev method when repeat is on

--- src/storage.coffee
+++ src/storage.coffee
@@ -32,12 +32,12 @@

   next: (current) ->
     cid = current.cid + 1
-    cid = 0 if not @images[cid] and @repeat
+    cid = 0 if @repeat and not @images[cid]
     return @images[cid]

   prev: (current) ->
     cid = current.cid - 1
-    cid = @length() if cid < 0 and @repeat
+    cid = @length() - 1 if @repeat and cid < 0
     return @images[cid]

   length: ->


Remove old file

Remove old file

--- src/twitter.coffee
+++ src/twitter.coffee
@@ -1,75 +0,0 @@
-https    = require 'https'
-{encode} = require 'b64'
-twitter  = require 'twitter-text'
-
-argv = require('optimist').usage('Missing username or password.\nUsage: $0')
-                          .demand('n')
-                          .alias('n', 'name')
-                          .describe('n', 'Twitter username')
-                          .demand('p')
-                          .alias('p', 'password')
-                          .describe('p', 'Twitter password')
-                          .default('hash', 'mac,iphone,ipad')
-                          .alias('h', 'hash')
-                          .describe('h', 'Search hash tag')
-                          .argv
-
-clients = []
-
-io = require('socket.io').listen(8080)
-io.sockets.on 'connection', (socket) -> clients.push socket
-
-request = https.get
-  headers: Authorization: 'Basic ' + encode argv.name + ':' + argv.password
-  host: 'stream.twitter.com'
-  port: 443
-  path: "/1.1/statuses/filter.json?include_entities=true&track=" + encodeURIComponent argv.hash
-  method: 'GET'
-
-request.on 'response', (response) ->
-  response.setEncoding 'utf8'
-
-  body = ''
-  response.on 'data', (chunk) ->
-    body += chunk
-
-    newline = body.indexOf "\r"
-    if newline isnt -1
-      try
-        message = body.slice 0, newline
-        if message? and message isnt ''
-          tweet = JSON.parse message
-
-          text = twitter.autoLink tweet.text
-          if tweet.entities?
-            if tweet.entities.urls? and tweet.entities.urls.length > 0
-              for entity in tweet.entities.urls
-                text = text.replace entity.url, entity.expanded_url
-                text = text.replace entity.url, entity.display_url
-
-            if tweet.entities.media? and tweet.entities.media.length > 0
-              for entity in tweet.entities.media
-                text = text.replace entity.url, entity.expanded_url
-                text = text.replace entity.url, entity.display_url
-
-          data =
-            id: tweet.id_str
-            link: "http://twitter.com/#{tweet.user.screen_name}"
-            avatar: tweet.user.profile_image_url
-            login: tweet.user.screen_name
-            name: tweet.user.name or tweet.user.screen_name
-            text: text
-
-      catch error
-        tweet = null
-        data = null
-        console.log "Error when parsing JSON: #{error}"
-
-      if data isnt null
-        clients.forEach (client) ->
-          if client and client.disconnected is false
-            client.send JSON.stringify data
-
-    body = body.slice newline + 1
-
-request.end()


New project text for #1

New project text for #1

--- project.coffee
+++ project.coffee
@@ -9,10 +9,10 @@
   id: 'bhl'
   background: 'background.jpg'

-  title: 'Illustrated Life'
-  summary: 'Help catalogue scientific illustrations'
+  title: 'Science Gossip'
+  summary: 'Uncover the history of citizen science'
   description: '''
-                 Illustrations are an essential part of visualising and understanding the natural world. We need your help to identify and classify the range of illustrations printed in books and periodicals over the last 200 years.
+                 In the Victorian period, just like today, scientists and members of the public worked together to further scientific discovery. Before computers and cameras they had to draw what they saw. Their drawings are locked away in the pages of Victorian periodicals, such as Science Gossip, Recreative Science and The Intellectual Observer. Help us to classify their drawings and map the origins of citizen science.
                  '''


Link Subject Preview to Discussion

Link Subject Preview to Discussion

--- app/talk/discussion-preview.cjsx
+++ app/talk/discussion-preview.cjsx
@@ -41,18 +41,14 @@

     if (@props.params?.owner and @props.params?.name) # get from url if possible
       {owner, name} = @props.params
-      projectTalk = "/projects/#{owner}/#{name}/talk/#{discussion.board_id}/#{discussion.id}"
-      <Link to={projectTalk} onClick={@logDiscussionClick.bind null, this}>{discussion.title}</Link>
+      "/projects/#{owner}/#{name}/talk/#{discussion.board_id}/#{discussion.id}"

     else if @props.project # otherwise fetch from project
       [owner, name] = @props.project.slug.split('/')
-      projectTalk = "/projects/#{owner}/#{name}/talk/#{discussion.board_id}/#{discussion.id}"
-      <Link to={projectTalk} onClick={@logDiscussionClick.bind null, this}>{discussion.title}</Link>
+      "/projects/#{owner}/#{name}/talk/#{discussion.board_id}/#{discussion.id}"

     else # link to zooniverse main talk
-      <Link to="/talk/#{discussion.board_id}/#{discussion.id}" onClick={@logDiscussionClick.bind null, this}>
-        {discussion.title}
-      </Link>
+      "/talk/#{discussion.board_id}/#{discussion.id}"

   render: ->
     {params, discussion} = @props
@@ -64,13 +60,17 @@
         {if @state.subject?
           subject = getSubjectLocation(@state.subject)

-            <Thumbnail src={subject.src} format={subject.format} width={100} height={150} controls={false} />
+            <Link to={@discussionLink()} onClick={@logDiscussionClick.bind null, this}>
+              <Thumbnail src={subject.src} format={subject.format} width={100} height={150} controls={false} />
+            </Link>

         }

           { if discussion.sticky}
-          {@discussionLink()}
+          <Link to={@discussionLink()} onClick={@logDiscussionClick.bind null, this}>
+            {discussion.title}
+          </Link>

         <LatestCommentLink {...@props} project={@props.project} discussion={discussion} comment={@props.comment} preview={true} />


Prevent extra reloading of project selector

--- app/talk/lib/project-linker.cjsx
+++ app/talk/lib/project-linker.cjsx
@@ -13,6 +13,9 @@

   componentWillMount: ->
     @setProjects()
+
+  shouldComponentUpdate: (nextProps, nextState) ->
+    nextState.projects isnt @state.projects

   goToProjectTalk: (projectId) ->
     apiClient.type('projects').get(projectId.toString()).then (project) =>


Optimize config templates a bit

Optimize config templates a bit

--- packages/shrub-skin/index.coffee
+++ packages/shrub-skin/index.coffee
@@ -189,7 +189,7 @@

 		templates[templatePath] = fs.readFileSync(
 			"#{skinPath}/app/template/#{templatePath}"
-		).toString 'utf8'
+		).toString('utf8').replace /\s+/g, ' '

 	skinAssets =


Use fair_id

Use fair_id

--- apps/fair/client/articles.coffee
+++ apps/fair/client/articles.coffee
@@ -4,9 +4,12 @@
 module.exports = class ArticlesAdapter
   constructor: ({ model, fair, el }) ->
     collection = new Articles
-    collection.url = "#{collection.url}/?fair_ids[]=#{fair.get('_id')}&published=true&limit=5&sort=-published_at"
     view = new ArticlesFeedView el: el, collection: collection
     el.html '

'
     el.addClass view.className
-    collection.fetch()
+    collection.fetch
+      data:
+        published: true
+        fair_id: fair.get('_id')
+        sort: '-published_at'
     view


Revert "Slugs are case insensitive now (closes #51)"

This reverts commit 8fb481cdd07b7f5fc6f8c033ec6f33066ac24736.

--- assets/scripts/app/routes.coffee
+++ assets/scripts/app/routes.coffee
@@ -195,7 +195,7 @@
           router.get('repoController').set 'repo', repo

         deserialize: (router, params) ->
-          slug = "#{params.owner}/#{params.name}".toLowerCase()
+          slug = "#{params.owner}/#{params.name}"
           repos = Travis.Repo.bySlug(slug)
           deferred = $.Deferred()


Home: Add widget HTML, CSS and JS codes to page.

--- client/landing/Intro/home.coffee
+++ client/landing/Intro/home.coffee
@@ -1,6 +1,8 @@
 class HomePage extends JView

   iframe = """"""
+
+  partialData = KD.customPartial?.partial or {}

   constructor:(options = {}, data)->

@@ -48,27 +50,34 @@
             "width=#{w},height=#{h},left=#{Math.floor (screen.width/2) - (w/2)},top=#{Math.floor (screen.height/2) - (h/2)}"

     @markers = new MarkerController
-
+    @widgetPlaceholder = new KDCustomHTMLView
+      cssClass         : "home-widget-placeholder"
+
+    if partialData.css
+      tag           = document.createElement "style"
+      tag.innerHTML = partialData.css
+
+      document.head.appendChild tag
+
+    if partialData.js
+      try
+        eval Encoder.htmlDecode partialData.js
+      catch
+        console.warn "Home page custom code failed to execute"

   showVideo:->
-
     @play.hide()
     @markers.hide 'teamwork'
     @$('figure.laptop section.teamwork').hide()
     @$('figure.laptop').append iframe

-
-
   hideVideo:->
-
     @play.show()
     @$('figure.laptop section.teamwork').show()
     @$('figure.laptop iframe').remove()
     KD.utils.wait 1000, => @markers.show 'teamwork'

-
   show:->
-
     @appendToDomBody()  unless document.getElementById 'home-page'

     @unsetClass 'out'
@@ -78,9 +87,7 @@

     KD.utils.defer => @markers.reset()

-
   hide:->
-
     @setClass 'out'
     document.body.classList.remove 'intro'

@@ -141,8 +148,8 @@
     @markers.group 'teamwork', vms, nav, chat, play

   pistachio:->
-    if KD.customPartial?.partial
-      return Encoder.htmlDecode KD.customPartial.partial.html
+    if partialData.html
+      return Encoder.htmlDecode partialData.html

     """

@@ -152,6 +159,7 @@
           LOGIN

+      {{> @widgetPlaceholder}}


disable coverage

disable coverage

--- tasks/tests.coffee
+++ tasks/tests.coffee
@@ -125,4 +125,4 @@
   runSequence('lint', 'mocha', cb)

 gulp.task 'travis', (cb) ->
-  runSequence('lint', 'mocha', 'istanbul', cb)
+  runSequence('lint', 'mocha', cb)


fixed test config

fixed test config

--- test/config.coffee
+++ test/config.coffee
@@ -1,8 +1,9 @@
 os = require "os"

 module.exports =
-  redis_host: process.env.REDIS_IP or "localhost"
-  redis_port: process.env.REDIS_PORT or 6379
+  redis:
+    host: process.env.REDIS_IP or "localhost"
+    port: process.env.REDIS_PORT or 6379
   cache_ttl: 30 * 60
   http_client_timeout: 4
   http_max_sockets: 20


Follow mixin

Follow mixin

--- test/follow.coffee
+++ test/follow.coffee
@@ -13,5 +13,6 @@
     widht: 10
     height: 10

+  enemy

 module()


improve tests

improve tests

--- test/hinoki.coffee
+++ test/hinoki.coffee
@@ -37,11 +37,11 @@
         'missing factory': (test) ->
             container = {}

-            block = ->
+            try
                 hinoki.inject container, (a) ->
-
-            test.throws block, Error, "missing factory for service 'a'"
-            test.done()
+            catch error
+                test.equals error.message, "missing factory for service 'a'"
+                test.done()

         'one factory': (test) ->
             container =
@@ -91,11 +91,28 @@
         'circular dependency': (test) ->
             container =
                 factories:
-                    a: (c) -> 1
-                    b: (a) -> a + 1
-                    c: (a, b) -> a + b + 1
+                    a: (c) ->
+                    b: (a) ->
+                    c: (a, b) ->

-            block = ->
+            try
                 hinoki.inject container, (a) ->
-            test.throws block, Error, "circular dependency a <- c <- a"
-            test.done()
+            catch error
+                test.equals error.message, "circular dependency a <- c <- a"
+                test.done()
+
+        'long circular dependency': (test) ->
+            container =
+                factories:
+                    a: (b) ->
+                    b: (c) ->
+                    c: (d) ->
+                    d: (e) ->
+                    e: (f) ->
+                    f: (a) ->
+
+            try
+                hinoki.inject container, (a) ->
+            catch error
+                test.equals error.message, "circular dependency a <- b <- c <- d <- e <- f <- a"
+                test.done()


added a simple modal example for product details.

--- public/views/product_view.coffee
+++ public/views/product_view.coffee
@@ -1,7 +1,11 @@
 class ProductView extends Backbone.View
+
+  events:
+    "click .epages-shop-product-link": "openProductDetails"
+
   template: _.template """

-      <img src="<%= image %>"/>
+      <img src="<%= image %>"/>

<%= name %>

         <%= price %>
@@ -16,3 +20,7 @@
       price: @model.attributes.priceInfo.price.formatted

     this
+
+  openProductDetails: (event) ->
+    event.preventDefault()
+    picoModal("Here goes the modal.").show()


make the email/password text big enough (10pt!) so I can actually see it.

--- src/smc-webapp/landing_page.cjsx
+++ src/smc-webapp/landing_page.cjsx
@@ -159,11 +159,11 @@
             <form onSubmit={@sign_in} className='form-inline pull-right' style={marginRight : -4 * UNIT, marginTop : 20}>
                 <Row>
                     <Col xs=4 style={col_style}>
-                        <Input style={marginRight : UNIT} ref='email' bsSize="small" type='email' placeholder='Email address' autoFocus={@props.has_account} onChange={@remove_error} />
+                        <Input style={marginRight : UNIT, fontSize:'10pt'} ref='email' bsSize="small" type='email' placeholder='Email address' autoFocus={@props.has_account} onChange={@remove_error} />
                     </Col>
                     <Col xs=4 style={col_style}>
-                        <Input style={marginRight : UNIT, marginBottom : "0px"} ref='password' bsSize="small" type='password' placeholder='Password' onChange={@remove_error} />
-                        Forgot Password?
+                        <Input style={marginRight : UNIT, marginBottom : "0px", fontSize:'10pt'} ref='password' bsSize="small" type='password' placeholder='Password' onChange={@remove_error} />
+                        Forgot Password?
                     </Col>
                     <Col xs=4 style={col_style}>
                         <Button type="submit" disabled={@props.signing_in} bsStyle="primary" bsSize="small" >Sign in</Button>


Fixes precise floating point math in equation builder #3809068

--- javascripts/lib/math/expression_equality.coffee
+++ javascripts/lib/math/expression_equality.coffee
@@ -121,7 +121,7 @@
         # The real "todo" here is that
         # numbers are internally of questionable state.
         # Im not entirely sure how to state that number expresison components are equal
-        check = "#{@value()}" == "#{other.value()}"
+        check = parseFloat("#{@value()}").toFixed(2) == parseFloat("#{other.value()}").toFixed(2)
         eq_calc.saveFalseForReport(check, @unrefined(), other, "Numeric values not equal")
     })


Edit class-level docs for up.tooltip

Edit class-level docs for up.tooltip

--- lib/assets/javascripts/unpoly/tooltip.js.coffee
+++ lib/assets/javascripts/unpoly/tooltip.js.coffee
@@ -4,20 +4,20 @@

 Unpoly comes with a basic tooltip implementation.

-You can an [`up-tooltip`](/up-tooltip) attribute to any HTML tag to show a tooltip whenever
-  the user hovers over the element:
+Add an [`up-tooltip`](/up-tooltip) attribute to any HTML tag to show a tooltip whenever
+the user hovers over the element:

       Decks

 \#\#\# Styling

-The [default styles](https://github.com/unpoly/unpoly/blob/master/lib/assets/stylesheets/up/tooltip.css.sass)
-show a simple tooltip with white text on a gray background.
+The default styles
+render a tooltip with white text on a gray background.
 A gray triangle points to the element.

-To change the styling, simply override CSS rules for the `.up-tooltip` selector and its `:after`
-selector that is used the triangle.
+To change the styling, simply override the [CSS rules](https://github.com/unpoly/unpoly/blob/master/lib/assets/stylesheets/up/tooltip.css.sass) for the `.up-tooltip` selector and its `:after`
+selector that is used for the triangle.

 The HTML of a tooltip element is simply this:


Remove references to TextEditor::scroll...

--- src/text-editor-component.coffee
+++ src/text-editor-component.coffee
@@ -306,7 +306,7 @@
     inputNode.value = event.data if insertedRange

   onVerticalScroll: (scrollTop) =>
-    return if @updateRequested or scrollTop is @editor.getScrollTop()
+    return if @updateRequested or scrollTop is @presenter.getScrollTop()

     animationFramePending = @pendingScrollTop?
     @pendingScrollTop = scrollTop
@@ -318,7 +318,7 @@
         @presenter.commitPendingScrollTopPosition()

   onHorizontalScroll: (scrollLeft) =>
-    return if @updateRequested or scrollLeft is @editor.getScrollLeft()
+    return if @updateRequested or scrollLeft is @presenter.getScrollLeft()

     animationFramePending = @pendingScrollLeft?
     @pendingScrollLeft = scrollLeft


:fire: Remove `@batch` from TextEditorPresenter

Please note that we will preserve the batching behavior but we will now simply
use booleans to track functions that ought to be called during `@getState`.

This (hopefully) expresses intent better, drawing a clear line between batched
functions and "realtime" ones.

--- src/text-editor-presenter.coffee
+++ src/text-editor-presenter.coffee
@@ -54,18 +54,6 @@
   # Returns a {Boolean}, `true` if is collecting changes, `false` if is applying them.
   isBatching: ->
     @updating is false
-
-  # Private: Executes `fn` if `isBatching()` is false, otherwise sets `@[flagName]` to `true` for later processing. In either cases, it calls `emitDidUpdateState`.
-  # * `flagName` {String} name of a property of this presenter
-  # * `fn` {Function} to call when not batching.
-  batch: (flagName, fn) ->
-    if @isBatching()
-      @[flagName] = true
-    else
-      fn.apply(this)
-      @[flagName] = false
-
-    @emitDidUpdateState()

   # Public: Gets this presenter's state, updating it just in time before returning from this function.
   # Returns a state {Object}, useful for rendering to screen.
@@ -133,7 +121,10 @@

       @emitDidUpdateState()
     @disposables.add @model.onDidChangeGrammar(@didChangeGrammar.bind(this))
-    @disposables.add @model.onDidChangePlaceholderText(@updateContentState.bind(this))
+    @disposables.add @model.onDidChangePlaceholderText =>
+      @shouldUpdateContentState = true
+
+      @emitDidUpdateState()
     @disposables.add @model.onDidChangeMini =>
       @updateScrollbarDimensions()
       @shouldUpdateScrollbarsState = true
@@ -248,16 +239,16 @@

     @resetShouldUpdateStates()

-  updateFocusedState: -> @batch "shouldUpdateFocusedState", ->
+  updateFocusedState: ->
     @state.focused = @focused

-  updateHeightState: -> @batch "shouldUpdateHeightState", ->
+  updateHeightState: ->
     if @autoHeight
       @state.height = @contentHeight
     else
       @state.height = null

-  updateVerticalScrollState: -> @batch "shouldUpdateVerticalScrollState", ->
+  updateVerticalScrollState: ->
     @state.content.scrollHeight = @scrollHeight
     @state.gutters.scrollHeight = @scrollHeight
     @state.verticalScrollbar.scrollHeight = @scrollHeight
@@ -266,14 +257,14 @@
     @state.gutters.scrollTop = @scrollTop
     @state.verticalScrollbar.scrollTop = @scrollTop

-  updateHorizontalScrollState: -> @batch "shouldUpdateHorizontalScrollState", ->
+  updateHorizontalScrollState: ->
     @state.content.scrollWidth = @scrollWidth
     @state.horizontalScrollbar.scrollWidth = @scrollWidth

     @state.content.scrollLeft = @scrollLeft
     @state.horizontalScrollbar.scrollLeft = @scrollLeft

-  updateScrollbarsState: -> @batch "shouldUpdateScrollbarsState", ->
+  updateScrollbarsState: ->
     @state.horizontalScrollbar.visible = @horizontalScrollbarHeight > 0
     @state.horizontalScrollbar.height = @measuredHorizontalScrollbarHeight
     @state.horizontalScrollbar.right = @verticalScrollbarWidth
@@ -282,7 +273,7 @@
     @state.verticalScrollbar.width = @measuredVerticalScrollbarWidth
     @state.verticalScrollbar.bottom = @horizontalScrollbarHeight

-  updateHiddenInputState: -> @batch "shouldUpdateHiddenInputState", ->
+  updateHiddenInputState: ->
     return unless lastCursor = @model.getLastCursor()

     {top, left, height, width} = @pixelRectForScreenRange(lastCursor.getScreenRange())
@@ -299,14 +290,14 @@
     @state.hiddenInput.height = height
     @state.hiddenInput.width = Math.max(width, 2)

-  updateContentState: -> @batch "shouldUpdateContentState", ->
+  updateContentState: ->
     @state.content.scrollWidth = @scrollWidth
     @state.content.scrollLeft = @scrollLeft
     @state.content.indentGuidesVisible = not @model.isMini() and @showIndentGuide
     @state.content.backgroundColor = if @model.isMini() then null else @backgroundColor
     @state.content.placeholderText = if @model.isEmpty() then @model.getPlaceholderText() else null

-  updateLinesState: -> @batch "shouldUpdateLinesState", ->
+  updateLinesState: ->
     return unless @startRow? and @endRow? and @lineHeight?

     visibleLineIds = {}
@@ -351,7 +342,7 @@
       top: row * @lineHeight
       decorationClasses: @lineDecorationClassesForRow(row)

-  updateCursorsState: -> @batch "shouldUpdateCursorsState", ->
+  updateCursorsState: ->
     @state.content.cursors = {}
     @updateCursorState(cursor) for cursor in @model.cursors # using property directly to avoid allocation
     return
@@ -369,7 +360,7 @@

     @emitDidUpdateState()

-  updateOverlaysState: -> @batch "shouldUpdateOverlaysState", ->
+  updateOverlaysState: ->
     return unless @hasOverlayPositionRequirements()

     visibleDecorationIds = {}
@@ -418,7 +409,7 @@

     return

-  updateLineNumberGutterState: -> @batch "shouldUpdateLineNumberGutterState", ->
+  updateLineNumberGutterState: ->
     @state.gutters.lineNumberGutter.maxLineNumberDigits = @model.getLineCount().toString().length

   updateCommonGutterState: ->
@@ -450,13 +441,12 @@
     @emitDidUpdateState()

   updateGutterOrderState: ->
-    @batch "shouldUpdateGutterOrderState", ->
-      @state.gutters.sortedDescriptions = []
-      if @model.isMini()
-        return
-      for gutter in @model.getGutters()
-        isVisible = @gutterIsVisible(gutter)
-        @state.gutters.sortedDescriptions.push({gutter, visible: isVisible})
+    @state.gutters.sortedDescriptions = []
+    if @model.isMini()
+      return
+    for gutter in @model.getGutters()
+      isVisible = @gutterIsVisible(gutter)
+      @state.gutters.sortedDescriptions.push({gutter, visible: isVisible})

   # Updates the decoration state for the gutter with the given gutterName.
   # @state.gutters.customDecorations is an {Object}, with the form:
@@ -469,25 +459,24 @@
   #     }
   #   }
   updateCustomGutterDecorationState: ->
-    @batch 'shouldUpdateCustomGutterDecorationState', =>
-      return unless @startRow? and @endRow? and @lineHeight?
-
-      @state.gutters.customDecorations = {}
-      return if @model.isMini()
-
-      for gutter in @model.getGutters()
-        gutterName = gutter.name
-        @state.gutters.customDecorations[gutterName] = {}
-        return if not @gutterIsVisible(gutter)
-
-        relevantDecorations = @customGutterDecorationsInRange(gutterName, @startRow, @endRow - 1)
-        relevantDecorations.forEach (decoration) =>
-          decorationRange = decoration.getMarker().getScreenRange()
-          @state.gutters.customDecorations[gutterName][decoration.id] =
-            top: @lineHeight * decorationRange.start.row
-            height: @lineHeight * decorationRange.getRowCount()
-            item: decoration.getProperties().item
-            class: decoration.getProperties().class
+    return unless @startRow? and @endRow? and @lineHeight?
+
+    @state.gutters.customDecorations = {}
+    return if @model.isMini()
+
+    for gutter in @model.getGutters()
+      gutterName = gutter.name
+      @state.gutters.customDecorations[gutterName] = {}
+      return if not @gutterIsVisible(gutter)
+
+      relevantDecorations = @customGutterDecorationsInRange(gutterName, @startRow, @endRow - 1)
+      relevantDecorations.forEach (decoration) =>
+        decorationRange = decoration.getMarker().getScreenRange()
+        @state.gutters.customDecorations[gutterName][decoration.id] =
+          top: @lineHeight * decorationRange.start.row
+          height: @lineHeight * decorationRange.getRowCount()
+          item: decoration.getProperties().item
+          class: decoration.getProperties().class

   gutterIsVisible: (gutterModel) ->
     isVisible = gutterModel.isVisible()
@@ -495,7 +484,7 @@
       isVisible = isVisible and @showLineNumbers
     isVisible

-  updateLineNumbersState: -> @batch "shouldUpdateLineNumbersState", ->
+  updateLineNumbersState: ->
     return unless @startRow? and @endRow? and @lineHeight?

     visibleLineNumberIds = {}
@@ -750,7 +739,7 @@
       @mouseWheelScreenRow = null
       @shouldUpdateLinesState = true
       @shouldUpdateLineNumbersState = true
-      @updateCustomGutterDecorationState()
+      @shouldUpdateCustomGutterDecorationState = true

     @emitDidUpdateState()

@@ -1119,7 +1108,7 @@

     @emitDidUpdateState()

-  updateDecorations: -> @batch "shouldUpdateDecorations", ->
+  updateDecorations: ->
     @lineDecorationsByScreenRow = {}
     @lineNumberDecorationsByScreenRow = {}
     @customGutterDecorationsByGutterNameAndScreenRow = {}


update table view

update table view

--- mabozen/templates/web/angular/table_mako.coffee
+++ mabozen/templates/web/angular/table_mako.coffee
@@ -32,7 +32,7 @@
         _t = translationService.translate

-        init ->
+        init = ()->
             $log.debug("init")

         ###
@@ -45,7 +45,7 @@
                 data: "${attr["column"]}"
                 title: _t("${attr["column"]}")
                 orderable: true
-                show: true
+                visible: true
     %if pkey == attr["column"]:
                 render: (data, type, row) ->
                     "" + data + ""
@@ -56,18 +56,18 @@
             {
                 data: "modifiedon"
                 title: _t("modifiedon")
-                show: false
+                visible: false
             }
             {
                 data: "createdon"
                 title: _t("createdon")
-                show: false
+                visible: false
             }
             {
                 data: "createdby"
                 title: _t("createdby")
                 orderable: false
-                show: false
+                visible: false
             }
         ]


Messing with tests.

Messing with tests.

--- test/bone.io.coffee
+++ test/bone.io.coffee
@@ -3,7 +3,9 @@
 rack = require('asset-rack')
 global.window = global
 global.$ = ->
-require('../bone.io')
+    fakeJquery = []
+    return fakeJquery
+require('../lib/index')

 describe 'a bone view', ->
     it "I have no idea what im doing", (done) ->


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/metered.coffee
+++ test/metered.coffee
@@ -13,7 +13,8 @@

   obj.include Metered

-  obj.meter 'health'
+  obj.meter
+    name: 'health'

   equals obj.I.maxHealth, 150


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/metered.coffee
+++ test/metered.coffee
@@ -9,7 +9,7 @@

 test "should set max<Attribute> if one doesn't exist", ->
   obj = GameObject
-    health:
+    health: 150

   obj.include Metered


movable velocity and acceleration getters

--- test/movable.coffee
+++ test/movable.coffee
@@ -38,7 +38,7 @@
 #    velocity: Point(7, 4)
 #    acceleration: Point(1, -0.3)
 #
-#    particle.update()
+#  particle.update(1)
 #
 #  equals particle.I.velocity.x, 11
 #  equals particle.I.velocity.y, 2.8


adding test modules

adding test modules

--- test/storage.coffee
+++ test/storage.coffee
@@ -1,7 +1,9 @@
-test "Storage", ->
+module "Storage"
+
+test "Local exists", ->
   ok(Local)

-test "Storage Local.set and Local.get", ->
+test "Local.set and Local.get", ->
   object =
     key: "test"
     cool: true
@@ -32,3 +34,5 @@
   ret = Local.get("__TEST")
   equal ret, ""

+ module undefined
+


removing unused session dependency

removing unused session dependency

--- src/scripts/collections/role-acceptances.coffee
+++ src/scripts/collections/role-acceptances.coffee
@@ -2,7 +2,6 @@
   Backbone = require('backbone')
   RoleAcceptances = require('cs!models/role-acceptances')
   settings = require('settings')
-  session  = require('cs!session')

   AUTHORING = "#{location.protocol}//#{settings.cnxauthoring.host}:#{settings.cnxauthoring.port}"


raspberrypi2.coffee: Change version
to yocto-morty instead of yocto-jethro

We now switch to yocto morty

Signed-off-by: Michal Mazurek <a2df1e659c9fd2578de0a26565357cb273292eeb@resin.io>

--- raspberrypi2.coffee
+++ raspberrypi2.coffee
@@ -22,7 +22,7 @@
 		machine: 'raspberrypi2'
 		image: 'resin-image'
 		fstype: 'resinos-img'
-		version: 'yocto-jethro'
+		version: 'yocto-morty'
 		deployArtifact: 'resin-image-raspberrypi2.resinos-img'
 		compressed: true


clear node and links fixed

clear node and links fixed

--- src/main/webapp/lib/views/MapNodeView.coffee
+++ src/main/webapp/lib/views/MapNodeView.coffee
@@ -166,9 +166,9 @@
     @model.toggle_selected()
     @toggleSelectedView()
     $a.broker.trigger("app:tree_remove_highlight:#{@model.cid}")
-    _.each(@model.ios(), (link) ->
-      io.link().set_selected(false)
-      $a.broker.trigger("app:tree_remove_highlight:#{link.get('link').cid}"))
+    _.each(@model.ios(), (ioLink) ->
+      ioLink.link().set_selected(false)
+      $a.broker.trigger("app:tree_remove_highlight:#{ioLink.link().cid}"))

   # This method is called from the context menu to select this nodes output or input links.
   # The type parameter determins whether we are grabbing output or input attributes on the node.


Revert "Update routes.coffee"

Revert "Update routes.coffee"

This reverts commit 9e4ee62272b9d8d5d89d0a2b3802c3470b930797.

--- server/controllers/routes.coffee
+++ server/controllers/routes.coffee
@@ -43,6 +43,7 @@
     'apps/:name*': all: [utils.isAuthenticated, apps.appWithSlash]

     'cozy/*': all: devices.replication
+    #'cozy/*': all: devices.external #access couchdb directly

     '.well-known/host-meta.?:ext': get: experiment.webfingerHostMeta
     '.well-known/:module': all: experiment.webfingerAccount


Have user avatar endpoint check that id is valid

To limit errors for client tests which send invalid ids

--- server/users/user_handler.coffee
+++ server/users/user_handler.coffee
@@ -506,6 +506,8 @@
           hipchat.sendHipChatMessage "#{req.body.githubUsername or req.user.get('name')} just signed the CLA.", ['main']

   avatar: (req, res, id) ->
+    if not isID(id)
+      return @sendBadInputError(res, 'Invalid avatar id')
     @modelClass.findById(id).exec (err, document) =>
       return @sendDatabaseError(res, err) if err
       return @sendNotFoundError(res) unless document


reduced complexity on module.exports

reduced complexity on module.exports

--- servers/lib/crawler/index.coffee
+++ servers/lib/crawler/index.coffee
@@ -127,6 +127,25 @@
   page   or = 1

+handleError = (err, content) ->
+  if err
+    console.error err
+
+    if err.error is 'moved_permanently'
+      desc = try JSON.parse err.description
+      location = '/Activity/Public'
+
+      if desc.typeConstant isnt 'group'
+        location = "/Activity/Topic/#{desc.rootName}"
+      return res.redirect 301, location
+
+    return res.status(404).send error_404()  if err.error is 'koding.NotFoundError'
+    return res.status(500).send error_500()
+  unless content
+    console.error 'not found'
+    return res.status(404).send error_404()
+
+
 module.exports =
   crawl: (bongo, { req, res, slug, isProfile }) ->
     { Base, race, dash, daisy } = require 'bongo'
@@ -136,24 +155,6 @@
     # if the section is not redirect them to public feed
     if name is 'Activity' and not section
       return res.redirect 301, "/#{name}/Public"
-
-    handleError = (err, content) ->
-      if err
-        console.error err
-
-        if err.error is 'moved_permanently'
-          desc = try JSON.parse err.description
-          location = '/Activity/Public'
-
-          if desc.typeConstant isnt 'group'
-            location = "/Activity/Topic/#{desc.rootName}"
-          return res.redirect 301, location
-
-        return res.status(404).send error_404()  if err.error is 'koding.NotFoundError'
-        return res.status(500).send error_500()
-      unless content
-        console.error 'not found'
-        return res.status(404).send error_404()

     { models } = bongo
     { generateFakeClient }   = require '../server/client'


格式调整,今天蛮多事，就不更新太多东西了

格式调整,今天蛮多事，就不更新太多东西了

--- tools/render.coffee
+++ tools/render.coffee
@@ -1,7 +1,6 @@
 fs = require 'fs'
 path = require 'path'
 jade = require 'jade'
-#pages =require './../views/viewConfig'

 pages = {}
 compiledJade = {}
@@ -19,7 +18,6 @@
   dirList = fs.readdirSync views
   dirList.forEach (item) ->
     if not fs.statSync(views + '/' + item).isDirectory()
-      #console.log item.indexOf('.jade')
       if item.indexOf('.jade') isnt -1
         pages[item.split('.')[0]] = item
     return


Update test for individual pair

Update test for individual pair

--- test/individual_pair_test.coffee
+++ test/individual_pair_test.coffee
@@ -1,5 +1,5 @@
 'use strict'
-{expect, assert} = require 'chai'
+{expect,AssertionError} = require 'chai'

 describe 'Individual.pair', ->
   Popuration = require '../lib/popuration'
@@ -75,7 +75,7 @@

       it 'should contains clone of parents if not enough probability', ->
         pair.crossover 0, ->
-          assert.false
+          throw new AssertionError 'crossover operator should not call'

         expect pair.offsprings
           .to.be.a 'array'
@@ -119,3 +119,7 @@
         .to.deep.equal [1, 1, 1, 1]
       expect offspring.fitness()
         .to.equal 4
+
+    it 'should not work if not enough probability', ->
+      pair.mutate 0, ->
+        throw new AssertionError 'mutation operator should not call'


Don't use deprecated APIs in specs

Don't use deprecated APIs in specs

--- spec/command-palette-spec.coffee
+++ spec/command-palette-spec.coffee
@@ -7,12 +7,16 @@

   beforeEach ->
     atom.workspaceView = new WorkspaceView
-    atom.workspaceView.openSync('sample.js')
+    activationPromise = null

-    activationPromise = atom.packages.activatePackage("command-palette")
+    waitsForPromise ->
+      atom.workspace.open('sample.js')

-    atom.workspaceView.attachToDom().focus()
-    atom.workspaceView.trigger 'command-palette:toggle'
+    runs ->
+      activationPromise = atom.packages.activatePackage("command-palette")
+
+      atom.workspaceView.attachToDom().focus()
+      atom.workspaceView.trigger 'command-palette:toggle'

     waitsForPromise ->
       activationPromise
@@ -25,7 +29,7 @@

   describe "when command-palette:toggle is triggered on the root view", ->
     it "shows a list of all valid command descriptions, names, and keybindings for the previously focused element", ->
-      keyBindings = atom.keymap.keyBindingsMatchingElement(atom.workspaceView.getActiveView())
+      keyBindings = atom.keymap.findKeyBindings(atom.workspaceView.getActiveView())
       for eventName, description of atom.workspaceView.getActiveView().events()
         eventLi = palette.find("[data-event-name='#{eventName}']")
         if description
@@ -33,7 +37,7 @@
           expect(eventLi.find('span')).toHaveText(description)
           expect(eventLi.find('span').attr('title')).toBe(eventName)
           for binding in keyBindings when binding.command == eventName
-            expect(eventLi.find(".key-binding:contains(#{_.humanizeKeystroke(binding.keystroke)})")).toExist()
+            expect(eventLi.find(".key-binding:contains(#{_.humanizeKeystroke(binding.keystrokes)})")).toExist()
         else
           expect(eventLi).not.toExist()

@@ -93,7 +97,7 @@
       atom.workspaceView.trigger 'command-palette:toggle'
       $(':focus').blur()
       atom.workspaceView.trigger 'command-palette:toggle'
-      keyBindings = atom.keymap.keyBindingsMatchingElement(atom.workspaceView.getActiveView())
+      keyBindings = atom.keymap.findKeyBindings(atom.workspaceView.getActiveView())
       for eventName, description of atom.workspaceView.events()
         eventLi = palette.list.children("[data-event-name='#{eventName}']")
         if description
@@ -101,7 +105,7 @@
           expect(eventLi.find('span')).toHaveText(description)
           expect(eventLi.find('span').attr('title')).toBe(eventName)
           for binding in keyBindings when binding.command is eventName
-            expect(eventLi.find(".key-binding:contains(#{_.humanizeKeystroke(binding.keystroke)})")).toExist()
+            expect(eventLi.find(".key-binding:contains(#{_.humanizeKeystroke(binding.keystrokes)})")).toExist()
         else
           expect(eventLi).not.toExist()

@@ -110,7 +114,7 @@
       atom.workspaceView.trigger 'command-palette:toggle'
       $(document.body).focus()
       atom.workspaceView.trigger 'command-palette:toggle'
-      keyBindings = atom.keymap.keyBindingsMatchingElement(atom.workspaceView.getActiveView())
+      keyBindings = atom.keymap.findKeyBindings(atom.workspaceView.getActiveView())
       for eventName, description of atom.workspaceView.events()
         eventLi = palette.list.children("[data-event-name='#{eventName}']")
         if description
@@ -118,6 +122,6 @@
           expect(eventLi.find('span')).toHaveText(description)
           expect(eventLi.find('span').attr('title')).toBe(eventName)
           for binding in keyBindings when binding.command is eventName
-            expect(eventLi.find(".key-binding:contains(#{_.humanizeKeystroke(binding.keystroke)})")).toExist()
+            expect(eventLi.find(".key-binding:contains(#{_.humanizeKeystroke(binding.keystrokes)})")).toExist()
         else
           expect(eventLi).not.toExist()


:new: [linter-behavior-spec] Add spec for auto-enabling behavior

--- spec/linter-behavior-spec.coffee
+++ spec/linter-behavior-spec.coffee
@@ -35,6 +35,13 @@
       trigger(bottomContainer.getTab('File'), 'click')
       expect(linter.views.panel.getVisibility()).toBe(true)

+    it 're-enables panel when another tab is clicked', ->
+      expect(linter.views.panel.getVisibility()).toBe(true)
+      trigger(bottomContainer.getTab('File'), 'click')
+      expect(linter.views.panel.getVisibility()).toBe(false)
+      trigger(bottomContainer.getTab('Project'), 'click')
+      expect(linter.views.panel.getVisibility()).toBe(true)
+
   describe 'Markers', ->
     it 'automatically marks files when they are opened if they have any markers', ->
       provider = getLinter()


:lipstick: Better test descriptions

:lipstick: Better test descriptions

--- spec/minimap-element-spec.coffee
+++ spec/minimap-element-spec.coffee
@@ -148,10 +148,10 @@
           expect(canvas.offsetWidth).toEqual(minimapElement.offsetWidth)
           expect(canvas.offsetHeight).toEqual(minimapElement.offsetHeight + minimap.getLineHeight())

-    describe 'when displayMinimapOnLeft setting is true', ->
+    describe 'when minimap.displayMinimapOnLeft setting is true', ->
       beforeEach ->
         atom.config.set 'minimap.displayMinimapOnLeft', true

-      it 'moves the attached to the left', ->
+      it 'moves the attached minimap to the left', ->
         expect(Array::indexOf.call(editorElement.shadowRoot.children, minimapElement)).toEqual(0)
         nextAnimationFrame()


Unit test to ensure StacktraceViews are re-used.

--- spec/stacktrace-view-spec.coffee
+++ spec/stacktrace-view-spec.coffee
@@ -27,7 +27,9 @@
     expect(opener '/some/other/path').toBeUndefined()

     trace.register()
-    expect(opener(trace.getUrl()).trace).toBe(trace)
+    stv = opener(trace.getUrl())
+    expect(stv.trace).toBe(trace)
+    expect(opener(trace.getUrl())).toBe(stv)

   it 'shows the error message', ->
     text = view.find('.error-message').text()


Fix typo in dispatcher spec.

Fix typo in dispatcher spec.

--- test/spec/dispatcher_spec.coffee
+++ test/spec/dispatcher_spec.coffee
@@ -400,7 +400,7 @@
     it 'should dispose when redirecting to a URL from controller action', (done) ->
       class RedirectingController extends Controller
         show: ->
-          dispatcher.controllerLoaded route1, null, {changeUrl: true}, Test1Controller
+          dispatcher.controllerLoaded route1, null, {changeURL: true}, Test1Controller

       dispose = sinon.spy RedirectingController.prototype, 'dispose'


Remove ship.cjsx

Remove ship.cjsx


fix some issues revealed by uncaught stracktraces

--- src/smc-hub/kucalc/compute-client.coffee
+++ src/smc-hub/kucalc/compute-client.coffee
@@ -97,7 +97,9 @@
         if not @logger?
             return ->
         else
-            return (args...) => @logger.debug("kucalc.Client.#{f}", args...)
+            # still need @logger? since it can get cleaned
+            # up when Project is being freed.
+            return (args...) => @logger?.debug("kucalc.Client.#{f}", args...)

     project: (opts) =>
         opts = defaults opts,
@@ -175,7 +177,9 @@
         if not @logger?
             return ->
         else
-            return (args...) => @logger.debug("kucalc.Project('#{@project_id}').#{f}", args...)
+            # still need @logger? since it can get cleaned
+            # up when Project is being freed.
+            return (args...) => @logger?.debug("kucalc.Project('#{@project_id}').#{f}", args...)

     # free -- stop listening for status updates from the database and broadcasting
     # updates about this project.
@@ -544,7 +548,7 @@
                     dbg("error -- #{err}")
                     opts.cb(err)
                     return
-                if x.state.state not in ['running', 'starting', 'pending']
+                if x.state?.state not in ['running', 'starting', 'pending']
                     dbg("project not active")
                     opts.cb()
                     return


Set the node process's default env param is empty object to fix the node process's stdout problem.

--- src/buffered-node-process.coffee
+++ src/buffered-node-process.coffee
@@ -41,13 +41,11 @@
         # Use a helper to prevent an icon from appearing on the Dock
         path.resolve(process.resourcesPath, '..', 'Frameworks',
                      'Atom Helper.app', 'Contents', 'MacOS', 'Atom Helper')
-      else if process.platform is 'win32'
-        'node'
       else
         process.execPath

     options ?= {}
-    options.env ?= Object.create(process.env)
+    options.env ?= {}
     options.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = 1

     args = args?.slice() ? []


Stop links from being labeled in lockdown mode [#158799297]

--- src/code/views/graph-view.coffee
+++ src/code/views/graph-view.coffee
@@ -45,7 +45,8 @@
       selectedNodes     = manager.getNodeInspection() or []
       editingNode       = manager.getNodeTitleEditing()[0] or null
       selectedLink      = manager.getLinkInspection() or []
-      editingLink       = manager.getLinkTitleEditing()[0] or null
+      # only allow link labels if simulation is not in lockdown mode
+      editingLink       = if not AppSettingsStore.store.settings.lockdown then manager.getLinkTitleEditing()[0] or null else false

       @setState
         selectedNodes: selectedNodes


try removing most of index

try removing most of index

--- views/index.coffee
+++ views/index.coffee
@@ -4,105 +4,105 @@
   for name, index in @people
     li ->
       a href: "/people/#{index}", -> name
-div id: 'messages'
-div id: 'chat_input', ->
-  input id: 'text_input', type: 'text'
-  input id: 'send_button', type: 'submit', value: 'Chat'
+# div id: 'messages'
+# div id: 'chat_input', ->
+#   input id: 'text_input', type: 'text'
+#   input id: 'send_button', type: 'submit', value: 'Chat'

-div id: 'chessboard', ->
-  table cellpadding: 0, cellspacing: 0, ->
-    for num in [8..1]
-      tr ->
-        for letter in ['a','b','c','d','e','f','g','h']
-          if num in [1,3,5,7] and letter in ['a','c','e','g']
-            td class: "dark #{num+letter}", ->
-              if num == 7
-                img src: 'images/chess_pieces/black_pawn.png', class: "chess_piece #{num+letter}"
-              if num == 1 and letter in ['a','h']
-                img src: 'images/chess_pieces/white_rook.png', class: "chess_piece #{num+letter}"
-              if num == 1 and letter in ['b','g']
-                img src: 'images/chess_pieces/white_knight.png', class: "chess_piece #{num+letter}"
-              if num == 1 and letter in ['c','f']
-                img src: 'images/chess_pieces/white_bishop.png', class: "chess_piece #{num+letter}"
-              if num == 1 and letter == 'e'
-                img src: 'images/chess_pieces/white_queen.png', class: "chess_piece #{num+letter}"
+# div id: 'chessboard', ->
+#   table cellpadding: 0, cellspacing: 0, ->
+#     for num in [8..1]
+#       tr ->
+#         for letter in ['a','b','c','d','e','f','g','h']
+#           if num in [1,3,5,7] and letter in ['a','c','e','g']
+#             td class: "dark #{num+letter}", ->
+#               if num == 7
+#                 img src: 'images/chess_pieces/black_pawn.png', class: "chess_piece #{num+letter}"
+#               if num == 1 and letter in ['a','h']
+#                 img src: 'images/chess_pieces/white_rook.png', class: "chess_piece #{num+letter}"
+#               if num == 1 and letter in ['b','g']
+#                 img src: 'images/chess_pieces/white_knight.png', class: "chess_piece #{num+letter}"
+#               if num == 1 and letter in ['c','f']
+#                 img src: 'images/chess_pieces/white_bishop.png', class: "chess_piece #{num+letter}"
+#               if num == 1 and letter == 'e'
+#                 img src: 'images/chess_pieces/white_queen.png', class: "chess_piece #{num+letter}"

-          else if num in [2,4,6,8] and letter in ['b','d','f','h']
-            td class: "dark #{num+letter}", ->
-              if num == 2
-                img src: 'images/chess_pieces/white_pawn.png', class: "chess_piece #{num+letter}"
-              if num == 8 and letter in ['a','h']
-                img src: 'images/chess_pieces/black_rook.png', class: "chess_piece #{num+letter}"
-              if num == 8 and letter in ['b','g']
-                img src: 'images/chess_pieces/black_knight.png', class: "chess_piece #{num+letter}"
-              if num == 8 and letter in ['c','f']
-                img src: 'images/chess_pieces/black_bishop.png', class: "chess_piece #{num+letter}"
-              if num == 8 and letter == 'd'
-                img src: 'images/chess_pieces/black_king.png', class: "chess_piece #{num+letter}"
+#           else if num in [2,4,6,8] and letter in ['b','d','f','h']
+#             td class: "dark #{num+letter}", ->
+#               if num == 2
+#                 img src: 'images/chess_pieces/white_pawn.png', class: "chess_piece #{num+letter}"
+#               if num == 8 and letter in ['a','h']
+#                 img src: 'images/chess_pieces/black_rook.png', class: "chess_piece #{num+letter}"
+#               if num == 8 and letter in ['b','g']
+#                 img src: 'images/chess_pieces/black_knight.png', class: "chess_piece #{num+letter}"
+#               if num == 8 and letter in ['c','f']
+#                 img src: 'images/chess_pieces/black_bishop.png', class: "chess_piece #{num+letter}"
+#               if num == 8 and letter == 'd'
+#                 img src: 'images/chess_pieces/black_king.png', class: "chess_piece #{num+letter}"

-          else
-            td class: "light #{num+letter}", ->
-              if num == 2
-                img src: 'images/chess_pieces/white_pawn.png', class: "chess_piece #{num+letter}"
-              if num == 7
-                img src: 'images/chess_pieces/black_pawn.png', class: "chess_piece #{num+letter}"
-              if num == 1 and letter in ['a','h']
-                img src: 'images/chess_pieces/white_rook.png', class: "chess_piece #{num+letter}"
-              if num == 1 and letter in ['b','g']
-                img src: 'images/chess_pieces/white_knight.png', class: "chess_piece #{num+letter}"
-              if num == 1 and letter in ['c','f']
-                img src: 'images/chess_pieces/white_bishop.png', class: "chess_piece #{num+letter}"
-              if num == 1 and letter == 'd'
-                img src: 'images/chess_pieces/white_king.png', class: "chess_piece #{num+letter}"
-              if num == 8 and letter in ['a','h']
-                img src: 'images/chess_pieces/black_rook.png', class: "chess_piece #{num+letter}"
-              if num == 8 and letter in ['b','g']
-                img src: 'images/chess_pieces/black_knight.png', class: "chess_piece #{num+letter}"
-              if num == 8 and letter in ['c','f']
-                img src: 'images/chess_pieces/black_bishop.png', class: "chess_piece #{num+letter}"
-              if num == 8 and letter == 'e'
-                img src: 'images/chess_pieces/black_queen.png', class: "chess_piece #{num+letter}"
-coffeescript ->
-  jQuery(document).ready ->
-    now.ready ->
-      $("#messages").show()
-      now.distributeMessage('has connected')
+#           else
+#             td class: "light #{num+letter}", ->
+#               if num == 2
+#                 img src: 'images/chess_pieces/white_pawn.png', class: "chess_piece #{num+letter}"
+#               if num == 7
+#                 img src: 'images/chess_pieces/black_pawn.png', class: "chess_piece #{num+letter}"
+#               if num == 1 and letter in ['a','h']
+#                 img src: 'images/chess_pieces/white_rook.png', class: "chess_piece #{num+letter}"
+#               if num == 1 and letter in ['b','g']
+#                 img src: 'images/chess_pieces/white_knight.png', class: "chess_piece #{num+letter}"
+#               if num == 1 and letter in ['c','f']
+#                 img src: 'images/chess_pieces/white_bishop.png', class: "chess_piece #{num+letter}"
+#               if num == 1 and letter == 'd'
+#                 img src: 'images/chess_pieces/white_king.png', class: "chess_piece #{num+letter}"
+#               if num == 8 and letter in ['a','h']
+#                 img src: 'images/chess_pieces/black_rook.png', class: "chess_piece #{num+letter}"
+#               if num == 8 and letter in ['b','g']
+#                 img src: 'images/chess_pieces/black_knight.png', class: "chess_piece #{num+letter}"
+#               if num == 8 and letter in ['c','f']
+#                 img src: 'images/chess_pieces/black_bishop.png', class: "chess_piece #{num+letter}"
+#               if num == 8 and letter == 'e'
+#                 img src: 'images/chess_pieces/black_queen.png', class: "chess_piece #{num+letter}"
+# coffeescript ->
+#   jQuery(document).ready ->
+#     now.ready ->
+#       $("#messages").show()
+#       now.distributeMessage('has connected')

-    setPosition = (className, top, left) ->
-      $("#messages").show()
-      now.updateElement(className, top, left)
+#     setPosition = (className, top, left) ->
+#       $("#messages").show()
+#       now.updateElement(className, top, left)

-    className = ""
-    $( ".chess_piece" ).draggable(
-      opacity: 0.55
-      refreshPositions: true
-      start: (event, ui) ->
-        className = ui.helper.context.className.toString()
-      stop: (event, ui) ->
-        piecePath= ui.helper.context.src.match(/chess_pieces*.*/)
-        pieceName = piecePath.toString().replace("chess_pieces/", "")
-        setPosition(className, ui.position.top, ui.position.left)
-        now.distributeMessage('has moved a piece')
-      )
+#     className = ""
+#     $( ".chess_piece" ).draggable(
+#       opacity: 0.55
+#       refreshPositions: true
+#       start: (event, ui) ->
+#         className = ui.helper.context.className.toString()
+#       stop: (event, ui) ->
+#         piecePath= ui.helper.context.src.match(/chess_pieces*.*/)
+#         pieceName = piecePath.toString().replace("chess_pieces/", "")
+#         setPosition(className, ui.position.top, ui.position.left)
+#         now.distributeMessage('has moved a piece')
+#       )

-    if $.cookie('klop_name')
-      now.name = $.cookie('klop_name')
-    else
-      now.name = prompt("What's your name?", "")
-      $.cookie('klop_name', now.name)
+#     if $.cookie('klop_name')
+#       now.name = $.cookie('klop_name')
+#     else
+#       now.name = prompt("What's your name?", "")
+#       $.cookie('klop_name', now.name)

-    $("#text_input").keyup (event) ->
-      if event.keyCode == 13
-        now.distributeMessage($("#text_input").val())
-        $("#text_input").val("")
+#     $("#text_input").keyup (event) ->
+#       if event.keyCode == 13
+#         now.distributeMessage($("#text_input").val())
+#         $("#text_input").val("")

-    $("#send_button").click( () ->
-      now.distributeMessage($("#text_input").val())
-      $("#text_input").val("")
-    )
+#     $("#send_button").click( () ->
+#       now.distributeMessage($("#text_input").val())
+#       $("#text_input").val("")
+#     )

-    now.receiveMessage = (name, message) ->
-      if message
-        $("#messages").append("
" + name + ": " + message + "
")
-    now.receiveElement= (className, top, left) ->
-      $(".#{className.replace(" ",  ".").replace(" ui-draggable", "")}").css({"position":"relative","left":"#{left}px","top":"#{top}px"})
+#     now.receiveMessage = (name, message) ->
+#       if message
+#         $("#messages").append("
" + name + ": " + message + "
")
+#     now.receiveElement= (className, top, left) ->
+#       $(".#{className.replace(" ",  ".").replace(" ui-draggable", "")}").css({"position":"relative","left":"#{left}px","top":"#{top}px"})


fixes Output domain "!=" constraint

fixes Output domain "!=" constraint

typo?

--- src/engine/domains/Output.coffee
+++ src/engine/domains/Output.coffee
@@ -20,7 +20,7 @@
     return a || b

   "!=": (a, b) ->
-    return a == b
+    return a != b

   "==": (a, b) ->
     return a == b


Update player.coffee

Update player.coffee

--- src/coffee/entities/player.coffee
+++ src/coffee/entities/player.coffee
@@ -2,7 +2,7 @@
 .body ->
   game.createClass "Player",
     init: (x, y) ->
-      @sprite = new game.Sprite("player.png")
+      @sprite = new game.Sprite "player.png"
       @sprite.addTo game.scene.stage
       @sprite.position.set x, y
       @sprite.anchor.set 0.5, 0.5


Call Range::toString, not ::inspect in DisplayBufferMarker::inspect

--- src/display-buffer-marker.coffee
+++ src/display-buffer-marker.coffee
@@ -168,7 +168,7 @@

   # Returns a {String} representation of the marker
   inspect: ->
-    "DisplayBufferMarker(id: #{@id}, bufferRange: #{@getBufferRange().inspect()})"
+    "DisplayBufferMarker(id: #{@id}, bufferRange: #{@getBufferRange()})"

   ### Internal ###


Check if the tour is ended when this is shown because the step has autoscroll enabled

--- src/coffee/bootstrap-tour.coffee
+++ src/coffee/bootstrap-tour.coffee
@@ -287,7 +287,7 @@
         @_showBackdrop(step) if step.backdrop

         showPopoverAndOverlay = =>
-          return if @getCurrentStep() isnt i
+          return if @getCurrentStep() isnt i or @ended()

           @_showOverlayElement step if step.element? and step.backdrop
           @_showPopover step, i


name label, avg label

name label, avg label

--- src/components/scores/index.cjsx
+++ src/components/scores/index.cjsx
@@ -101,7 +101,7 @@

     if heading.average
       summary =
-        {(heading.average * 100).toFixed(1)}%
+        {(heading.average * 100).toFixed(1)}% avg

     sortingHeader = <SortingHeader type={heading.type} sortKey={i}
@@ -156,7 +156,7 @@
     emptyCell =

     header =
       <SortingHeader sortKey='name' sortState={@state.sort} onSort={@changeSortingOrder}>
-        Class
+        Student Name
       </SortingHeader>
     dueDateHeading =
Due Date

     customHeader =


Render selector warning markdown

Render selector warning markdown

--- lib/deprecation-cop-view.coffee
+++ lib/deprecation-cop-view.coffee
@@ -215,9 +215,10 @@
                 @a class: 'source-url', href: path.join(deprecations[0].packagePath, sourcePath), sourcePath
                 @ul class: 'list', =>
                   for deprecation in deprecations
-                    @li class: 'list-item', =>
+                    @li class: 'list-item deprecation-detail', =>
                       @span class: 'text-warning icon icon-alert'
-                      @span class: 'list-item deprecation-message', deprecation.message
+                      @div class: 'list-item deprecation-message', =>
+                        @raw marked(deprecation.message)

                       @div class: 'btn-toolbar', =>
                         if url = self.createSelectorIssueUrl(packageName, deprecation, sourcePath)


component.io: Handle missing schema files

Fixme, should load yaml schemas instead...

--- schema/index.coffee
+++ schema/index.coffee
@@ -1,3 +1,6 @@
-module.exports =
-  testcase: require './testcase'
-  testsuite: require './testsuite'
+try
+  module.exports =
+    testcase: require './testcase'
+    testsuite: require './testsuite'
+catch e
+  console.log 'fbp-spec: Failed to load schemas', e


use url module instead of regex to determine if a link is relative, treat links with a leading slash as relative (e.g. /archive.html).

--- src/plugins/markdown-page.coffee
+++ src/plugins/markdown-page.coffee
@@ -9,7 +9,7 @@

 is_relative = (uri) ->
   ### returns true if *uri* is relative; otherwise false ###
-  !/(^\w+:)|(^\/)/.test uri
+  (url.parse(uri).protocol == undefined)

 parseMetadata = (metadata, callback) ->
   ### takes *metadata* in the format:


Add function to display grouped values in console

--- .config/init.coffee
+++ .config/init.coffee
@@ -57,3 +57,15 @@
 # Undo whitespace molestation applied by Project-Manager
 {exec} = require "child_process"
 exec "cd #{__dirname}/.. && make could-you-not"
+
+
+# Print a message to the console.
+#
+# If more than one argument is provided, they're grouped together in an expandable list.
+log = (text, args...) ->
+	if args.length
+		console.groupCollapsed text
+		console.log(i) for i in args
+		console.groupEnd()
+	else
+		console.trace text


Add a comment

Add a comment

--- src/smc-util/upgrade-spec.coffee
+++ src/smc-util/upgrade-spec.coffee
@@ -18,6 +18,10 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ###############################################################################
+
+###
+IMPORTANT: If you change this file, also update the date in webapp-lib/policies/pricing.pug
+###

 ###
 Define upgrades to projects.


lame fix for sso buttons not working with FA 5.

--- src/smc-webapp/landing_page.cjsx
+++ src/smc-webapp/landing_page.cjsx
@@ -24,7 +24,7 @@
 ###
 {rclass, React, ReactDOM, redux, rtypes} = require('./smc-react')
 {Alert, Button, ButtonToolbar, Col, Modal, Grid, Row, FormControl, FormGroup, Well, ClearFix, Checkbox} = require('react-bootstrap')
-{ErrorDisplay, Icon, Loading, ImmutablePureRenderMixin, Footer, UNIT, COLORS, ExampleBox, Space} = require('./r_misc')
+{ErrorDisplay, Icon, Loading, ImmutablePureRenderMixin, Footer, UNIT, COLORS, ExampleBox, Space, Tip} = require('./r_misc')
 {HelpEmailLink, SiteName, SiteDescription, TermsOfService, AccountCreationEmailInstructions} = require('./customize')

 DESC_FONT = 'sans-serif'
@@ -50,6 +50,7 @@
         small_size  : rtypes.bool
         no_header   : rtypes.bool
         style       : rtypes.object
+        github_hack : rtypes.bool

     styles :
         facebook :
@@ -62,7 +63,6 @@
             backgroundColor : "#55ACEE"
             color           : "white"
         github   :
-            backgroundColor : "black"
             color           : "black"

     render_strategy: (name) ->
@@ -75,11 +75,26 @@
             size = undefined
         else
             size = '2x'
-
-            <Icon size={size} name='stack' href={url}>
-                {<Icon name='circle' stack='2x' style={color: @styles[name].backgroundColor} /> if name isnt 'github'}
-                <Icon name={name} stack='1x' size={'2x' if name is 'github'} style={color: @styles[name].color} />
-            </Icon>
+        style = misc.copy(@styles[name])
+        if name == 'github'
+            style.color = 'black'
+            style.position = 'absolute'
+            style.fontSize = '50px'
+            style.marginTop = '-10px'
+        else
+            style.display = 'inline-block'
+            style.padding = '8px'
+            style.borderRadius = '50%'
+            style.width = '50px'
+            style.height=  '50px'
+            style.marginRight = '10px'
+            style.textAlign = 'center'
+        cname = misc.capitalize(name)
+        title = <Icon name={name} /> {cname}
+
+            <Tip placement='bottom' title={title} tip={"Use #{cname} to sign into your CoCalc account instead of an email address and password."}>
+                <Icon name={name} style={style} />
+            </Tip>

     render_heading: ->
@@ -88,10 +103,15 @@

Connect with

     render: ->
+        strategies = @props.strategies?.toJS() ? []
+        strategies = ['facebook', 'google', 'twitter', 'github']   # for testing.
+        if @props.github_hack and 'github' in strategies
+            # hack for now to get around using position absolute.
+            github_hack = {marginLeft: '-50px'}

             {@render_heading()}
-

-                {@render_strategy(name) for name in @props.strategies?.toJS() ? []}
+

+                {@render_strategy(name) for name in strategies}

@@ -141,6 +161,7 @@
         if @props.strategies.size > 1

                 <Passports
+                    github_hack = {true}
                     strategies  = {@props.strategies}
                     get_api_key = {@props.get_api_key}
                     style       = {textAlign: 'center'}


due date cut off for last task...

due date cut off for last task...

--- src/smc-webapp/tasks/editor.cjsx
+++ src/smc-webapp/tasks/editor.cjsx
@@ -135,7 +135,7 @@
             scroll               = {@props.local_view_state?.get('scroll')}
             scroll_into_view     = {@props.scroll_into_view}
             font_size            = {@props.local_view_state?.get('font_size')}
-            style                = {overflowX:'hidden', overflowY:'auto', paddingBottom: '200px'}
+            style                = {overflowX:'hidden', overflowY:'auto', paddingBottom: '300px'}
             sortable             = {not @props.read_only and is_sortable(@props.local_view_state?.getIn(['sort', 'column']))}
             read_only            = {@props.read_only}
             selected_hashtags    = {@props.local_view_state?.get('selected_hashtags')}


Use inline timeout settings.

Use inline timeout settings.

--- src/spec/integration.spec.coffee
+++ src/spec/integration.spec.coffee
@@ -8,8 +8,6 @@
 {SphereClient} = require 'sphere-node-sdk'

 describe 'integration test', ->
-
-  jasmine.getEnv().defaultTimeoutInterval = 10000

   beforeEach (done) ->

@@ -39,6 +37,7 @@
       @order = result.body
       done()
     .catch (error) -> done(_.prettify(error))
+  , 10000

   afterEach (done) ->

@@ -52,6 +51,7 @@
       @product = null
       @productType = null
       @order = null
+  , 10000

   describe 'Update order state', ->

@@ -72,6 +72,7 @@
         expect(result.body.shippingInfo.deliveries[0].parcels[0].trackingData.isReturn).toBe isReturn
         done()
       .catch (err) -> done(_.prettify err)
+    , 10000

     it 'it should update orderState, shipmentState and shippingInfo of an existing order', (done) ->
       trackingId = uniqueId 't-'
@@ -81,6 +82,7 @@
       .catch (err) ->
         expect(err).toBe '[SphereOrderStatusImport]  No order found with orderNumber \'unavailable\'.'
         done()
+    , 10000

     it 'it should update orderState, shipmentState and shippingInfo of an existing order only once', (done) ->
       trackingId = uniqueId 't-'
@@ -102,6 +104,7 @@
         expect(result3.body.version).toBe @result1.body.version
         done()
       .catch (err) -> done(_.prettify err)
+    , 10000

   ###
   helper methods