tried to correct guard around hack for Firefox XHR/CORS headers... kinda working

--- lib/assets/javascripts/firehose/long_poll.js.coffee
+++ lib/assets/javascripts/firehose/long_poll.js.coffee
@@ -42,21 +42,24 @@
     data.last_message_sequence = @_lastMessageSequence
     # TODO: Some of these options will be deprecated in jQuery 1.8
     #       See: http://api.jquery.com/jQuery.ajax/#jqXHR
-    $.ajax @config.longPoll.url,
+    opts =
       crossDomain:  true
       data:         data
       timeout:      @_timeout
       success:      @_success
       error:        @_error
-      xhr:          hackAroundFirefoxXhrHeadersBug if $.browser is 'mozilla'
       complete:     @_xhrComplete
+    opts.xhr = hackAroundFirefoxXhrHeadersBug if $.browser.mozilla
+    $.ajax @config.longPoll.url, opts

   _xhrComplete: (jqXhr) =>
     console?.log "XHR complete", arguments
     # Get the last sequence from the server if specified.
+    console?.log "status #{jqXhr.status}"
     if jqXhr.status == 200
-      @_lastMessageSequence = jqXhr.getResponseHeader @messageSequenceHeader
-      console?.log "@_lastMessageSequence => #{@_lastMessageSequence}"
+      val = jqXhr.getResponseHeader @messageSequenceHeader
+      @_lastMessageSequence = val if val?
+      console?.log "Header #{@messageSequenceHeader} => #{val}"
       if @_lastMessageSequence == null
         console?.log 'ERROR: Unable to get last message sequnce from header'

@@ -68,11 +71,12 @@
     console?.log "_success", arguments
     @_open data
     return if @_stopRequestLoop
+    console?.log "status #{jqXhr.status}"
     if jqXhr.status == 204
       # If we get a 204 back, that means the server timed-out and sent back a 204 with a
       # X-Http-Next-Request header
       #
-      # Why did we use a 204 and not a 408? Because FireFox is really stupid about 400 level error
+      # Why did we use a 204 and not a 408? Because Firefox is really stupid about 400 level error
       # codes and would claims its a 0 error code, which we use for something else. Firefox is IE
       # in this case
       @connect(@_okInterval)
@@ -112,14 +116,15 @@
 # jQuery.ajaxSettings.xhr was breaking regular IE7 loading. Better to localize
 # this anyway to solve that problem and loading order issues.
 hackAroundFirefoxXhrHeadersBug = ->
+  console?.log "Hacking AJAX response headers for Firefox"
+  XHR_HEADERS = [
+    "Cache-Control", "Content-Language", "Content-Type"
+    "Expires", "Last-Modified", "Pragma"
+  ]
   xhr = jQuery.ajaxSettings.xhr()
   originalFun = xhr.getAllResponseHeaders
   xhr.getAllResponseHeaders = ->
-    XHR_HEADERS = [
-      "Cache-Control", "Content-Language", "Content-Type"
-      "Expires", "Last-Modified", "Pragma"
-    ]
-    return allHeaders if (allHeaders = originalFun.call xhr)?
+    return allHeaders if allHeaders = originalFun.call xhr
     lines = for name in XHR_HEADERS when xhr.getResponseHeader(name)?
       "#{name}: #{xhr.getResponseHeader name}"
     lines.join '\n'
@@ -129,6 +134,7 @@
 # This code was shamelessly stolen from:
 # https://github.com/jaubourg/ajaxHooks/blob/master/src/ajax/xdr.js
 if $.browser.msie and parseInt($.browser.version, 10) in [8, 9]
+  console?.log "Hacking AJAX CORS for Internet Explorer"
   jQuery.ajaxTransport (s) ->
     if s.crossDomain and s.async
       if s.timeout


fix  reference

fix  reference

--- src/main/webapp/lib/extensions/Sensor.coffee
+++ src/main/webapp/lib/extensions/Sensor.coffee
@@ -45,8 +45,8 @@

 window.beats.Sensor::from_position = (position, link) ->
   s = new window.beats.Sensor
-  p = new $a.Position()
-  pt = new $a.Point()
+  p = new window.beats.Position()
+  pt = new window.beats.Point()
   pt.set(
           {
             'lat':position.lat(),
@@ -59,7 +59,8 @@
   s.set('display_position', p)
   s.set('type', 'static_point')
   s.set('link', link || null)
-  s.set('link_reference', new $a.Link_reference().set('id', link?.ident() || null))
+  id = link?.ident() || null
+  s.set('link_reference', new window.beats.Link_reference().set('id', id))
   s

 window.beats.Sensor::defaults =


Attempt to achieve higher uploade transfer rates in WebRTC

--- src/public/library/models/remote.peer.coffee
+++ src/public/library/models/remote.peer.coffee
@@ -96,7 +96,7 @@

 			unless @isChannelOpen()
 				return false
-
+
 			try
 				@_channel.send(message.serialize())
 				return true
@@ -120,12 +120,24 @@
 			@_channel.onclose = @_onChannelClose
 			@_channel.onerror = @_onChannelError

+		# Ups bandwidth limit on SDP. Meant to be called during offer/answer.
+		_higherBandwidthSDP: ( sdp ) ->
+			# AS stands for Application-Specific Maximum.
+			# Bandwidth number is in kilobits / sec.
+			# See RFC for more info: http://www.ietf.org/rfc/rfc2327.txt
+			parts = sdp.split 'b=AS:30'
+			replace = 'b=AS:102400' # 100 Mbps
+			if parts.length > 1
+				return parts[0] + replace + parts[1]
+			return sdp
+
 		# Is called when a local description has been added. Will send this description
 		# to the remote.
 		#
 		# @param description [RTCSessionDescription] the local session description
 		#
 		_onLocalDescription: ( description ) =>
+			description.sdp = @_higherBandwidthSDP(description.sdp)
 			@_connection.setLocalDescription(description)
 			@_controller.server.emitTo(@id, 'peer.setRemoteDescription', @_controller.id, description)


updating method name for polyfill

updating method name for polyfill

--- src/scripts/modules/media/title/title.coffee
+++ src/scripts/modules/media/title/title.coffee
@@ -19,7 +19,7 @@

     templateHelpers: () ->
       title = @title()
-      location.origin = socialMedia.locationOriginPolyFillForIe()
+      location.origin = socialMedia.locationOrigin()

       return {
         share: socialMedia.socialMediaInfo(@summary(), @title())


feat (Modules) Writing a file logs a human readable event to the console

--- src/steroids/module/writeJsonStringTo.coffee
+++ src/steroids/module/writeJsonStringTo.coffee
@@ -1,4 +1,11 @@
 fs = require 'fs'
+chalk = require 'chalk'
+paths = require '../paths'

-module.exports = writeJsonStringTo = (filename) -> (json) ->
-  fs.writeFileSync filename, json
+module.exports = writeJsonStringTo = (filepath) -> (json) ->
+  fs.writeFileSync filepath, json
+  wroteFile filepath
+
+wroteFile = (filepath) ->
+  filename = filepath.replace paths.applicationDir, '.'
+  console.log "#{chalk.bold.green '>'} Wrote #{filename}"


enh: generalized code for polygon generation

--- src/core/regular_tiling.coffee
+++ src/core/regular_tiling.coffee
@@ -1,19 +1,15 @@
 "use strict"
 {eliminateFinalA} = require "./vondyck_rewriter.coffee"
 {VonDyck} = require "./vondyck.coffee"
-#{} = require "./field.coffee"
-
-#???
-{unity} = require "./vondyck_chain.coffee"
 {NodeHashMap} = require "./chain_map.coffee"
-
+M = require "./matrix3.coffee"

 exports.RegularTiling = class RegularTiling extends VonDyck
   constructor: (n,m) ->
     super(n,m,2)
     @solve()
     if @type() == "hyperbolic"
-      @cellShape = @_generateNGon n, @representation.sinh_r, @representation.cosh_r
+      @cellShape = @_generateNGon @representation

   toString: -> "VonDyck(#{@n}, #{@m}, #{@k})"

@@ -104,8 +100,16 @@
     getCellList cells

   #produces shape (array of 3-vectors)
-  _generateNGon: (n, sinh_r, cosh_r) ->
-    alpha = Math.PI*2/n
-    for i in [0...n]
-      angle = alpha*i
-      [sinh_r*Math.cos(angle), sinh_r*Math.sin(angle), cosh_r]
+  _generateNGon: (representation) ->
+    #Take center of generator B and rotate it by action of A
+
+    if representation.k is 2
+      for i in [0...representation.n]
+        M.mulv representation.aPower(i), representation.centerB
+    else
+      for i2 in [0...representation.n*2]
+        i = (i2/2) | 0
+        if i2 & 1 is 0
+          M.mulv representation.aPower(i), representation.centerB
+        else
+          M.mulv representation.aPower(i), representation.centerAB


Added missing icons for ios: 50/50@2x/60

--- src/tasks/build/after/local/ios/icons.coffee
+++ src/tasks/build/after/local/ios/icons.coffee
@@ -22,11 +22,20 @@
     if icons?.ios?.icon40x2
       grunt.file.copy icons.ios.icon40x2, path.join(res, 'icon-40@2x.png'), encoding: null

+    if icons?.ios?.icon50
+      grunt.file.copy icons.ios.icon50, path.join(res, 'icon-50.png'), encoding: null
+
+    if icons?.ios?.icon60x2
+      grunt.file.copy icons.ios.icon50x2, path.join(res, 'icon-50@2x.png'), encoding: null
+
     if icons?.ios?.icon57
       grunt.file.copy icons.ios.icon57, path.join(res, 'icon.png'), encoding: null

     if icons?.ios?.icon57x2
       grunt.file.copy icons.ios.icon57x2, path.join(res, 'icon@2x.png'), encoding: null
+
+    if icons?.ios?.icon60
+      grunt.file.copy icons.ios.icon60, path.join(res, 'icon-60.png'), encoding: null

     if icons?.ios?.icon60x2
       grunt.file.copy icons.ios.icon60x2, path.join(res, 'icon-60@2x.png'), encoding: null


pass array indices

pass array indices

--- src/es5-basic/es5-basic.coffee
+++ src/es5-basic/es5-basic.coffee
@@ -38,21 +38,21 @@
     Array.prototype.map = (fn, that) -> (fn.call(that, val, i, this) for val, i in this when i of this)

 if not Array.prototype.filter
-    Array.prototype.filter = (fn, that) -> (val for val, i in this when i of this and fn.call(that, val))
+    Array.prototype.filter = (fn, that) -> (val for val, i in this when i of this and fn.call(that, val, i, this))

+if not Array.prototype.some
+    Array.prototype.some = (fn, that) ->
+        for val, i in this
+            if i of this
+                if fn.call(that, val, i, this)
+                    return true
+        return false
+
 if not Array.prototype.every
     Array.prototype.every = (fn, that) ->
         for val, i in this
             if i of this
-                if not fn.call(that, val)
-                    return false
-        return true
-
-if not Array.prototype.some
-    Array.prototype.some = (fn, that) ->
-        for val in this
-            if i of this
-                if fn.call(that, val)
+                if not fn.call(that, val, i, this)
                     return false
         return true

@@ -94,17 +94,17 @@

 if not Array.prototype.indexOf
     Array.prototype.indexOf = (value) ->
-            i = arguments[1] ? 0
-            i += length if i < 0
-            i = Math.max(i, 0)
-
-            while i < @length
-                if i of this
-                    if this[i] == value
-                        return i
-                i++
+        i = arguments[1] ? 0
+        i += length if i < 0
+        i = Math.max(i, 0)
+
+        while i < @length
+            if i of this
+                if this[i] == value
+                    return i
+            i++

-            return -1
+        return -1

 if not Array.prototype.lastIndexOf
     Array.prototype.lastIndexOf = (value) ->


Removed logging of authenticated user.

Removed logging of authenticated user.

--- src/api/authentication.coffee
+++ src/api/authentication.coffee
@@ -42,7 +42,6 @@

 	if (hash.digest('hex') === authToken) {
 		// authenticated
-		logger.info('User ' +email+ ' made an authenticated requets to the API from ' +this.request.host);
 		yield next;
 	} else {
 		// not authenticated - token mismatch


some stubs for dynamic column work

some stubs for dynamic column work

--- src/app/cases/cases.js.coffee
+++ src/app/cases/cases.js.coffee
@@ -18,12 +18,42 @@

+
+# .factory "Case", (Restangular)->
+#   # collection methods
+#   # - methods for querying cases
+
+
+# .factory "Field", (Restangular)->
+#   Field = (schema_id)->
+#   #Restangular.service()
+
+
+# .factory "Column",
+
+#   # Sets the type of thing the column will show.
+#   # Options are:
+#   # - Field
+#   # - Question
+#   Column = (id,type)->
+#     this.id = id
+#     this.type = type
+
+
+
+
+
+
+
+
+
+
 .controller "CaseListCtrl",
   ($scope, Restangular, $state, $stateParams,
   current_schema, current_question_set, evaluationService)->

     $scope.question_set = current_question_set # a service
-    $scope.schema = current_schema
+    $scope.schema = current_schema
     $scope.cases = []
     $scope.evaluationService = evaluationService


Require path in phpcbf

Require path in phpcbf

--- src/beautifiers/phpcbf.coffee
+++ src/beautifiers/phpcbf.coffee
@@ -4,6 +4,7 @@

 "use strict"
 Beautifier = require('./beautifier')
+path = require('path')

 module.exports = class PHPCBF extends Beautifier
   name: "PHPCBF"


Removed log statements

Removed log statements

--- src/coffee/controllers.coffee
+++ src/coffee/controllers.coffee
@@ -17,11 +17,9 @@
   Controllers.controller 'StartingPointCtrl', Array '$scope', '$routeParams', 'startHistory', (scope, params, startHistory) ->

     startHistory scope
-    console.log params.tool

     scope.$watch 'startingPoints', (startingPoints) -> if startingPoints
       scope.tool = L.find startingPoints, (sp) -> sp.ident is params.tool
-      console.log scope.tool

   Controllers.controller 'AboutCtrl', Array '$http', '$scope', 'startHistory', (http, scope, startHistory) ->
     http.get('/tools', {params: {capabilities: 'initial'}})


Fix DEBUG definition

Fix DEBUG definition

--- src/coffeescripteditor.coffee
+++ src/coffeescripteditor.coffee
@@ -4,7 +4,7 @@
 @extends TextEditor
 ###
 class Rubic.CoffeeScriptEditor extends Rubic.TextEditor
-  DEBUG = if DEBUG? then DEBUG else 0
+  DEBUG = Rubic.DEBUG or 0
   Rubic.Editor.addEditor(this)

   ###*


made value optional

made value optional

--- src/completelysuckless.coffee
+++ src/completelysuckless.coffee
@@ -68,8 +68,8 @@
     require: "sucklessComplete"
     transclude: true
     scope:
-      # this is the input value bound from outer scope
-      value: "="
+      # this is the optional input value bound from outer scope
+      value: "=?"

       # use this callback if you don't bind an object for your value
       # inheritance/double binding is not working on primitive values
@@ -86,7 +86,7 @@

       # callback to compare two objects
       # this is used to preserve the selection upon reload of choices
-      identity: "="
+      identity: "=?"

     template: '<div class="suckless-complete">
       <input type="text" data-ng-model="value" placeholder="{{ placeholder }}"/>


coralEDA: fix slot generation

coralEDA: fix slot generation

--- src/coraleda-generator.coffee
+++ src/coraleda-generator.coffee
@@ -153,14 +153,19 @@
               fs.writeSync(fd, "       }\n") # end ps_circ
             else # padstack.width != padstack.height
               line_thickness = if padstack.width > padstack.height then padstack.height else padstack.width
-              if layer.endsWith("Mask")
-                line_thickness += 2 * (padstack.mask || pattern.settings.clearance.padToMask || 0)
               fs.writeSync(fd, "       ha:ps_line {\n")
-              fs.writeSync(fd, sprintf("        x1 = #{@f}mm\n", padstack.width / -2 + line_thickness / 2))
-              fs.writeSync(fd, sprintf("        y1 = #{@f}mm\n", padstack.height / -2 + line_thickness / 2))
-              fs.writeSync(fd, sprintf("        x2 = #{@f}mm\n", padstack.width / 2 - line_thickness / 2))
-              fs.writeSync(fd, sprintf("        y2 = #{@f}mm\n", padstack.height / 2 - line_thickness / 2))
-              fs.writeSync(fd, sprintf("        thickness = #{@f}mm\n", line_thickness))
+              if padstack.width > padstack.height
+                fs.writeSync(fd, sprintf("        x1 = #{@f}mm\n", padstack.width / -2 + line_thickness / 2))
+                fs.writeSync(fd, sprintf("        y1 = #{@f}mm\n", 0))
+                fs.writeSync(fd, sprintf("        x2 = #{@f}mm\n", padstack.width / 2 - line_thickness / 2))
+                fs.writeSync(fd, sprintf("        y2 = #{@f}mm\n", 0))
+              else
+                fs.writeSync(fd, sprintf("        x1 = #{@f}mm\n", 0))
+                fs.writeSync(fd, sprintf("        y1 = #{@f}mm\n", padstack.height / -2 + line_thickness / 2))
+                fs.writeSync(fd, sprintf("        x2 = #{@f}mm\n", 0))
+                fs.writeSync(fd, sprintf("        y2 = #{@f}mm\n", padstack.height / 2 - line_thickness / 2))
+              mask = if layer.endsWith("Mask") then (padstack.mask || pattern.settings.clearance.padToMask || 0) else 0
+              fs.writeSync(fd, sprintf("        thickness = #{@f}mm\n", line_thickness + mask * 2))
               fs.writeSync(fd, "        square = 0\n") # 0=round cap; 1=square cap
               fs.writeSync(fd, "       }\n") # end line
           when 'rectangle'


adapted cache to deal with {}

adapted cache to deal with {}

--- src/driver/driverCache.coffee
+++ src/driver/driverCache.coffee
@@ -94,6 +94,7 @@
     return ret

   put: (condensedQuery, root) ->
+    return unless root.prop or root.splits
     filter = condensedQuery[0].filter
     hashValue = @hashmap[filterToHash(filter)] ?= {}
     for k, v of root.prop
@@ -154,6 +155,7 @@
     return @hashmap[generateHash(condensedQuery)]

   put: (condensedQuery, root) ->
+    return unless root.prop or root.splits
     hash = generateHash(condensedQuery)
     splitOpName = condensedQuery[1].split.name
     hashValue = []
@@ -204,6 +206,8 @@
     splitOpName = splitOp.name
     applysAfterSplit = condensedQuery[1].applies.map((command) -> return command.name)

+    return root unless root.prop or root.splits
+
     # Handle 1 split for now
     for split in root.splits
       splitName = split.prop[splitOpName]


Fix spec name

Fix spec name

--- spec/project-spec.coffee
+++ spec/project-spec.coffee
@@ -170,7 +170,7 @@
         absolutePath = fs.absolute(__dirname)
         expect(atom.project.resolve(absolutePath)).toBe absolutePath

-  describe ".setPath(path)", ->
+  describe ".setPaths(path)", ->
     describe "when path is a file", ->
       it "sets its path to the files parent directory and updates the root directory", ->
         atom.project.setPaths([require.resolve('./fixtures/dir/a')])


window.load for lazy load images

window.load for lazy load images

--- app/javascript/lazy_load_images.coffee
+++ app/javascript/lazy_load_images.coffee
@@ -34,7 +34,7 @@
   noscript_wrapped_images = document.querySelectorAll(ELEMENTS_QUERY)
   noscript_wrapped_images.forEach(lazy_load_image_in_noscript_wrapper)

-document.addEventListener "load", ->
+window.addEventListener "load", ->
   lazy_load_images()

 document.addEventListener "turbolinks:load", ->


Removed old file

Removed old file

--- core/app/backbone/views/facts/discussion_view2.coffee
+++ core/app/backbone/views/facts/discussion_view2.coffee
@@ -1,13 +0,0 @@
-class window.DiscussionView2 extends Backbone.Marionette.Layout
-  tagName: 'section'
-  className: 'discussion2'
-
-  template: 'facts/discussion2'
-
-  regions:
-    factRegion: '.fact2-region'
-    evidenceRegion: '.evidence-region'
-
-  onRender: ->
-    @factRegion.show new TopFactView(model: @model)
-    @evidenceRegion.show new TopFactEvidenceView(model: @model)


SocialWorker: JAccount: remove shared AccountAuthenticated event

--- workers/social/lib/social/models/account.coffee
+++ workers/social/lib/social/models/account.coffee
@@ -47,7 +47,6 @@
       type               : 'ascending'
     sharedEvents    :
       static        : [
-        { name : 'AccountAuthenticated' } # TODO: we need to handle this event differently.
         { name : 'RemovedFromCollection' }
       ]
       instance      : [


Groups: corrected options

Groups: corrected options

--- workers/social/lib/social/models/account.coffee
+++ workers/social/lib/social/models/account.coffee
@@ -1424,9 +1424,7 @@
         targetName: "JDomain"
         sourceId  : @getId()
         sourceName: "JAccount"
-      ,
-        targetId : 1
-      , (err, rels)->
+      , {}, (err, rels)->
         return callback err if err

         selector = $or : [


SocialWorker: JAccount: followHappened event listeners

--- workers/social/lib/social/models/account.coffee
+++ workers/social/lib/social/models/account.coffee
@@ -295,8 +295,6 @@

   constructor: ->
     super
-    @notifyOriginWhen 'PrivateMessageSent', 'FollowHappened'
-    @notifyGroupWhen 'FollowHappened'

   @sendUpdateInstanceEvent = (obj, op) ->
     JAccount.bongos.forEach (bongo) ->


account: remove from super admin

account: remove from super admin

--- workers/social/lib/social/models/account.coffee
+++ workers/social/lib/social/models/account.coffee
@@ -747,9 +747,8 @@

   dummyAdmins = [ "sinan", "devrim", "gokmen", "chris", "fatihacet", "arslan",
-                  "sent-hil", "kiwigeraint", "cihangirsavas", "leventyalcin",
-                  "leeolayvar", "stefanbc", "szkl", "canthefason", "nitin",
-                  "rsbrown"]
+                  "sent-hil", "cihangirsavas", "leeolayvar", "stefanbc",
+                  "szkl", "canthefason", "nitin"]

   userIsExempt: (callback)->
     # console.log @isExempt, this


Profile: counts are not reset and stuck as 1 when decrement operation occurs problem is fixed

--- workers/social/lib/social/models/account.coffee
+++ workers/social/lib/social/models/account.coffee
@@ -848,7 +848,8 @@
       targetId   : @getId()
       sourceName : 'JAccount'
     , (err, count)=>
-      return if err or not count
+      return if err
+      count ?= 0
       @update ($set: 'counts.following': count), ->

     # Member Follower count
@@ -857,7 +858,8 @@
       sourceId   : @getId()
       sourceName : 'JAccount'
     , (err, count)=>
-      return if err or not count
+      return if err
+      count ?= 0
       @update ($set: 'counts.followers': count), ->

     # Tag Following count
@@ -866,7 +868,8 @@
       targetId   : @getId()
       sourceName : 'JTag'
     , (err, count)=>
-      return if err or not count
+      return if err
+      count ?= 0
       @update ($set: 'counts.topics': count), ->

     # Status Update count
@@ -875,7 +878,8 @@
       targetId   : @getId()
       sourceName : 'JNewStatusUpdate'
     , (err, count)=>
-      return if err or not count
+      return if err
+      count ?= 0
       @update ($set: 'counts.statusUpdates': count), ->

     # Comments count
@@ -884,14 +888,16 @@
       targetId   : @getId()
       sourceName : 'JNewStatusUpdate'
     , (err, count)=>
-      return if err or not count
+      return if err
+      count ?= 0
       @update ($set: 'counts.comments': count), ->

     # ReferredUsers count
     JAccount.count
       referrerUsername : @profile.nickname
     , (err, count)=>
-      return if err or not count
+      return if err
+      count ?= 0
       @update ($set: 'counts.referredUsers': count), ->

     # Invitations count
@@ -899,7 +905,8 @@
       username   : @profile.nickname
       invited    : true
     , (err, count)=>
-      return if err or not count
+      return if err
+      count ?= 0
       @update ($set: 'counts.invitations': count), ->

     # Last Login date
@@ -919,7 +926,8 @@
       targetName : 'JAccount'
       sourceName : 'JAccount'
     , (err, count)=>
-      return if err or not count
+      return if err
+      count ?= 0
       @update ($set: 'counts.staffLikes': count), ->

   dummyAdmins = [ "sinan", "devrim", "gokmen", "chris", "fatihacet", "arslan",


watchify working too, this is a good starting point

--- Gulpfile.coffee
+++ Gulpfile.coffee
@@ -19,7 +19,17 @@
     .pipe(source('./web/cs/dream.coffee'))
     .pipe(rename('dream.js'))
     .pipe(gulp.dest('./web/js/'))
-
+gulp.task 'watchify', () ->
+  bundler = watchify('./web/cs/dream.coffee')
+  bundler.transform(coffeeify)
+  rebundle = () ->
+    bundle = bundler.bundle({debug: true})
+    bundle
+      .pipe(source('./web/cs/dream.coffee'))
+      .pipe(rename('dream.js'))
+      .pipe(gulp.dest('./web/js/'))
+  bundler.on('update', rebundle)
+  rebundle()
 ###
 watchify = "watchify
   app/assets/javascripts/initialize.coffee


Fix file removal. Closes gh-579.

Fix file removal. Closes gh-579.

--- src/fs_utils/file_list.coffee
+++ src/fs_utils/file_list.coffee
@@ -149,5 +149,5 @@
         @compileDependencyParents path
       else
         file = @find path
-        file.removed = true
+        file.removed = true if file and not file.disposed
     @resetTimer()


fix(core): remove unused code

fix(core): remove unused code

--- packages/core/src/session.coffee
+++ packages/core/src/session.coffee
@@ -78,7 +78,6 @@
   # Start with a paused scheduler to register actions out of the handler
   action.scheduler = schedulers.out
   # Expose the action context
-  action.config.context = action.context if action.context
   action.context = new Proxy on_call, get: on_get
   # Execute the action
   result = new Promise (resolve, reject) ->


Sidebar: vmModal minor code styling

Sidebar: vmModal minor code styling

--- client/Main/maincontroller/mainviews/mainview.coffee
+++ client/Main/maincontroller/mainviews/mainview.coffee
@@ -220,15 +220,11 @@
   openVMModal: (vm, item) ->

     bounds   = item.getBounds()
-
-    top      = bounds.y - 80
-    left     = bounds.x + bounds.w + 30
-
-    new VMSettingsModal
-      position     :
-        top        : Math.max top, 0
-        left       : left
-    , vm
+    position =
+      top    : Math.max bounds.y - 80, 0
+      left   : bounds.x + bounds.w + 30
+
+    new VMSettingsModal {position}, vm

   setStickyNotification:->


Client: Activity: Added onMentionClick event handler. it sets input value with a mension.

--- client/activity/lib/components/feeditem/index.coffee
+++ client/activity/lib/components/feeditem/index.coffee
@@ -96,6 +96,23 @@
       <MessageLikeSummary message={message} />
     </div>

+
+  onMentionClick: (reply) ->
+
+    kd.utils.stopDOMEvent event
+
+    account = reply.get 'account'
+    textInput = ReactDOM.findDOMNode @refs.textInput
+
+    fetchAccount account.toJS(), (err, account) =>
+      return  unless account
+
+      inputValue = if textInput.value then "#{textInput.value} " else ""
+      value      = "#{inputValue}@#{account.profile.nickname} "
+
+      @setState { comment: value, hasValue: yes }, ->
+        textInput.focus()
+
   render: ->
     { message } = @props
     <div className={kd.utils.curry 'FeedItem', @props.className}>


activity: render correct component

activity: render correct component

--- client/activity/lib/routes/allprivatechannels.coffee
+++ client/activity/lib/routes/allprivatechannels.coffee
@@ -1,4 +1,4 @@
-BrowsePrivateChannelsModal = require 'activity/components/browsepublicchannelsmodal'
+BrowsePrivateChannelsModal = require 'activity/components/browseprivatechannelsmodal'

 module.exports = class AllPrivateChannelsRoute


Client: Activity: Deleted tabIndex properties and wrapped modal content with `form` element

--- client/app/lib/components/activitymodal/index.coffee
+++ client/app/lib/components/activitymodal/index.coffee
@@ -19,16 +19,13 @@
     buttonConfirmClassName : 'Button--danger'
     buttonExtraTitle       : null
     buttonExtraClassName   : 'Button--primary'
-    buttonConfirmTabIndex  : null
-    buttonAbortTabIndex    : null
-    buttonExtraTabIndex    : null

   renderExtraButton: ->

     return null  unless @props.buttonExtraTitle

-    <Modal.Button className={@props.buttonExtraClassName} tabIndex={@props.buttonExtraTabIndex}  onClick={@props.onButtonExtraClick}>
+    <Modal.Button className={@props.buttonExtraClassName} onClick={@props.onButtonExtraClick}>
       {@props.buttonExtraTitle}
     </Modal.Button>

@@ -36,18 +33,20 @@
   render: ->
     <Modal {...@props}>
       <Modal.Title>{@props.title}</Modal.Title>
-      <Modal.Content>
-        {@props.children}
-      </Modal.Content>
-      <Modal.ButtonGroup>
-        <Modal.Button tabIndex={@props.buttonConfirmTabIndex} className={@props.buttonConfirmClassName} onClick={@props.onConfirm}>
-          {@props.buttonConfirmTitle}
-        </Modal.Button>
-        {@renderExtraButton()}
-        <Modal.Button tabIndex={@props.buttonAbortTabIndex} className={@props.buttonAbortClassName} onClick={@props.onAbort}>
-          {@props.buttonAbortTitle}
-        </Modal.Button>
-      </Modal.ButtonGroup>
+      <form>
+        <Modal.Content>
+          {@props.children}
+        </Modal.Content>
+        <Modal.ButtonGroup>
+          <Modal.Button className={@props.buttonConfirmClassName} onClick={@props.onConfirm}>
+            {@props.buttonConfirmTitle}
+          </Modal.Button>
+          {@renderExtraButton()}
+          <Modal.Button className={@props.buttonAbortClassName} onClick={@props.onAbort}>
+            {@props.buttonAbortTitle}
+          </Modal.Button>
+        </Modal.ButtonGroup>
+      </form>
     </Modal>


shortcuts: minor

shortcuts: minor

--- client/app/lib/shortcuts/views/listcontroller.coffee
+++ client/app/lib/shortcuts/views/listcontroller.coffee
@@ -9,9 +9,8 @@
   constructor: (options={}, data) ->

     options = _.extend {}, options,
-      selection: true
-      view: new kd.ListView
-        cssClass: 'shortcuts-list'
-        itemClass: ShortcutsListItem
+      view        : new kd.ListView
+        cssClass  : 'shortcuts-list'
+        itemClass : ShortcutsListItem

     super options, data


double cloak of invisibility

double cloak of invisibility

--- components/block_collection/client/block_view.coffee
+++ components/block_collection/client/block_view.coffee
@@ -68,8 +68,13 @@
     e.preventDefault()
     e.stopImmediatePropagation()

+    console.log "@model.get('visibility')", @model.get('visibility')
+
     if @model.get('visibility') is 'private'
-      window.open "#{sd.APP_URL}/go?redirect-to=#{url}",'_blank'
+      site = window.open "", "hide_referrer"
+      site.document.open()
+      site.document.writeln '<script type="text/javascript">window.location = "' + "#{sd.APP_URL}/go?redirect-to=#{url}" + '";</script>'
+      site.document.close()
     else
       window.open url,'_blank'
       return false


Document up.Response type

Document up.Response type

--- lib/assets/javascripts/unpoly/classes/response.coffee
+++ lib/assets/javascripts/unpoly/classes/response.coffee
@@ -3,6 +3,15 @@
 u = up.util

 ###*
+The `up.Response` type describes the server response to an [`AJAX request`](/up.request).
+
+\#\#\# Example
+
+    up.request('/foo').then(function(response) {
+      console.log(response.status); // 200
+      console.log(response.text);   // "<html><body>..."
+    });
+
 @class up.Response
 ###
 class up.Response extends up.Record
@@ -91,11 +100,39 @@
   constructor: (options) ->
     super(options)

+  ###*
+  Returns whether the server responded with a 2xx HTTP status.
+
+  @function up.Response.prototype.isSuccess
+  @return {boolean}
+  @experimental
+  ###
   isSuccess: =>
     @status && (@status >= 200 && @status <= 299)

+  ###*
+  Returns whether the response was not [successful](/up.Request.prototype.isSuccess).
+
+  This also returns `true` when the request encountered a [fatal error](/up.Request.prototype.isFatalError)
+  like a timeout or loss of network connectivity.
+
+  @function up.Response.prototype.isSuccess
+  @return {boolean}
+  @experimental
+  ###
   isError: =>
     !@isSuccess()

+  ###*
+  Returns whether the request encountered a [fatal error](/up.Request.prototype.isFatalError)
+  like a timeout or loss of network connectivity.
+
+  When the server produces an error message with an HTTP status like `500`,
+  this is not considered a fatal error and `false` is returned.
+
+  @function up.Response.prototype.isSuccess
+  @return {boolean}
+  @experimental
+  ###
   isFatalError: =>
     @isError() && u.isBlank(@text)


work with going back on turbolinks

work with going back on turbolinks

--- resources/assets/coffee/forum/topic-ajax.coffee
+++ resources/assets/coffee/forum/topic-ajax.coffee
@@ -53,11 +53,19 @@

 $(document).on 'ajax:success', '.js-forum-poll-edit', (e, data, status, xhr) ->
-  $(e.target)
-    .trigger('ajax:complete', [xhr, status])
+  $(e.target).trigger('ajax:complete', [xhr, status])

-  original = $('.js-forum-poll').html()
-  $('.js-forum-poll').html(data)
+  $poll = $('.js-forum-poll')

-  $('.js-forum-poll-edit-cancel').on 'click', () ->
-    $('.js-forum-poll').html(original)
+  $poll
+    .attr 'data-original-poll', $poll.html()
+    .html data
+
+  osu.pageChange()
+
+
+$(document).on 'click', '.js-forum-poll-edit-cancel', ->
+  $poll = $('.js-forum-poll')
+  $poll.html $poll.attr('data-original-poll')
+
+  osu.pageChange()


major fix - testing url was deployed.

major fix - testing url was deployed.

--- assets/coffeescript/pupil_store.coffee
+++ assets/coffeescript/pupil_store.coffee
@@ -489,7 +489,7 @@

           testing_url = "https://script.google.com/macros/s/AKfycbyPEqIjIfyWR09vPhd5HcP7jB9KIjng0YzEwo2tjWOk8aEscM4/exec"
           production_url = "https://script.google.com/macros/s/AKfycbz6VPh0yqNOmAChtPa9C1Ot9dk_JwHWj_vWPIZlPzr4YodmTvs/exec"
-          url = testing_url
+          url = production_url

           $.ajax
             type: 'POST'


Fix parenthesis normalizaation in search strings

--- assets/javascripts/app/searcher.coffee
+++ assets/javascripts/app/searcher.coffee
@@ -113,7 +113,8 @@
     fuzzy_min_length: 3

   SEPARATORS_REGEXP = /\:?\ |#|::|->/g
-  PARANTHESES_REGEXP = /\(\w.*?\)$/
+  INFO_PARANTHESES_REGEXP = /\(\w+?\)$/
+  EMPTY_PARANTHESES_REGEXP = /\(\)/
   EVENT_REGEXP = /\ event$/
   DOT_REGEXP = /\.+/g
   WHITESPACE_REGEXP = /\s/g
@@ -129,7 +130,8 @@
       .replace EVENT_REGEXP, EMPTY_STRING
       .replace SEPARATORS_REGEXP, SEPARATOR
       .replace DOT_REGEXP, SEPARATOR
-      .replace PARANTHESES_REGEXP, EMPTY_STRING
+      .replace INFO_PARANTHESES_REGEXP, EMPTY_STRING
+      .replace EMPTY_PARANTHESES_REGEXP, EMPTY_STRING
       .replace WHITESPACE_REGEXP, EMPTY_STRING

   constructor: (options = {}) ->


Changed no results row to be a common one with label and button with action

--- Framework/Views/iOS/Controls/SearchResultsTableNoResultsRow_Framework_iOS.coffee
+++ Framework/Views/iOS/Controls/SearchResultsTableNoResultsRow_Framework_iOS.coffee
@@ -4,8 +4,32 @@

     @noResultsRow = Ti.UI.createTableViewRow({
       backgroundColor: "#FFF"
+      selectionStyle: Ti.UI.iPhone.TableViewCellSelectionStyle.NONE
       height: "100%"
-      touchEnabled: false
-      selectionStyle: Ti.UI.iPhone.TableViewCellSelectionStyle.NONE
       type: "noResultsRow"
-    })+    })
+
+    label = Ti.UI.createLabel({
+      text: "No Results"
+      font: { fontSize: 18 }
+      textAlign: "center"
+    })
+    @noResultsRow.add(label)
+
+    button = root.app.create("Button", {
+      text: "Reset Search"
+      fontSize: 15
+      height: 36
+      width: 250
+      bottom: 50
+      style: {
+        gradient: ["#0082cc", "#0045cc"]
+        borderColor: '#0062b8'
+        labelShadowColor: "#000"
+      }
+      onClickStyle: {
+        gradient: ['#003cb4', '#0044cc']
+      }
+      onClick: @options.resetResultsOnClick
+    })
+    @noResultsRow.add(button.view)


Make CartoDB formatter available for Indicator formatting

--- models/indicator.coffee
+++ models/indicator.coffee
@@ -9,7 +9,8 @@
   cartodb: require('../getters/cartodb')

 FORMATTERS =
-  gdoc = require('../formatters/gdoc')
+  gdoc: require('../formatters/gdoc')
+  cartodb: require('../formatters/cartodb')

 module.exports = class Indicator
   constructor: (attributes) ->


Updated the fixture fictitions

Updated the fixture fictitions

--- dev/data/fixtures/fictitious/fixture.coffee
+++ dev/data/fixtures/fictitious/fixture.coffee
@@ -1 +1,22 @@
 'use strict'
+lorem = require 'lorem-ipsum'
+server = require 'angnode-server'
+bootstrap = require '../../configs/bootstrapper.js'
+
+simpleWord = ->
+    output = lorem {
+        count: 1,
+        sentenceLowerBound: 1,
+        sentenceUpperBound: 1
+    }
+    output.substr 0, output.length - 1
+
+console.log simpleWord()
+
+###b = new bootstrap
+
+s = new server
+
+s.bootstrap(b).run (app, server) ->
+    console.log 'Connected to : ' + app.get 'port'###
+


user: no reason to defer this schema def.

--- workers/social/lib/social/models/user.coffee
+++ workers/social/lib/social/models/user.coffee
@@ -82,7 +82,7 @@
         type        : String
         validate    : require('./name').validateName
         set         : (value)-> value.toLowerCase()
-      uid           : ->
+      uid           :
         type        : Number
         set         : Math.floor
       email         :


Socialapi: init bot message endpoint improved

--- client/Main/socialapicontroller.coffee
+++ client/Main/socialapicontroller.coffee
@@ -367,8 +367,8 @@
       mapperFn           : mapPrivateMessages

     initPrivateMessageFromBot : messageRequesterFn
-      fnName                  : 'initPrivateMessage'
-      validateOptionsWith     : ['body', 'recipients']
+      fnName                  : 'initPrivateMessageFromBot'
+      validateOptionsWith     : ['body']
       mapperFn                : mapPrivateMessages

     sendPrivateMessageFromBot : messageRequesterFn


client: added default options into search controller

--- client/app/lib/searchcontroller.coffee
+++ client/app/lib/searchcontroller.coffee
@@ -115,11 +115,17 @@
     remote.api.JAccount.one query
       .then (it) -> [it]

-  searchAccounts: (seed) ->
+  searchAccounts: (seed, options = {}) ->
+
+    opt =
+      hitsPerPage                  : 10
+      restrictSearchableAttributes : [ "nick" ]
+
+    opt = kd.utils.extend opt, options

     seed = seed.replace /[^-\w]/g, ''

-    @search 'accounts', seed, hitsPerPage : 10
+    @search 'accounts', seed, opt
       .then (data) ->
         throw new Error "No data!" if data.length is 0
         return data


Set font-weight to normal in sa-order-stash-plugin

--- src/plugins/order_stash.coffee
+++ src/plugins/order_stash.coffee
@@ -54,6 +54,7 @@
     text-align: center;
     letter-spacing: 0;
     font-family: Verdana, Arial, sans-serif !important;
+    font-weight: normal !important;
     box-shadow: 0px 1px 11px 0px rgba(77,77,77,0.33);

     #{switch configuration.position


NEW: insertAtCursor && copy IMPROVED: enter event has props for ctrlKey, altKey, etc... see KeyboardEvent

--- source/Art/Engine/Forms/TextInputElement.coffee
+++ source/Art/Engine/Forms/TextInputElement.coffee
@@ -1,10 +1,9 @@
 # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input
-
-
 {defineModule, log, merge, select, inspect, wordsArray, timeout, max} = require 'art-standard-lib'
 {rgbColor, point} = require 'art-atomic'

 Foundation = require 'art-foundation'
+{isIOS} = Foundation.Browser
 {createElementFromHtml} = Foundation.Browser.Dom
 {TextArea, Input} = Foundation.Browser.DomElementFactories
 SynchronizedDomOverlay = require "./SynchronizedDomOverlay"
@@ -112,8 +111,8 @@

         handlerMap.keyPress? e
         {props} = e
-        @handleEvent "enter",  value: @value if props.key == "Enter"
-        @handleEvent "escape", value: @value if props.key == "Escape"
+        @handleEvent "enter",  merge props, value: @value if props.key == "Enter"
+        @handleEvent "escape", merge props, value: @value if props.key == "Escape"

   _unregister: ->
     @_canvasElementToFocusOnBlur?.focusCanvas()
@@ -145,3 +144,53 @@

   selectAll: ->
     @domElement.select()
+
+  copy: ->
+    el = @domElement
+
+    if isIOS()
+      {readOnly, contentEditable} = el
+
+      el.contentEditable  = true
+      el.readOnly         = false
+
+      range = document.createRange()
+      range.selectNodeContents el
+
+      sel = window.getSelection()
+
+      sel.removeAllRanges()
+      sel.addRange          range
+      el.setSelectionRange  0, 999999
+
+      result = document.execCommand 'copy'
+
+      el.contentEditable    = contentEditable
+      el.readOnly           = readOnly
+      sel.removeAllRanges()
+      el.blur()
+
+      result
+    else
+      el.select()
+      document.execCommand 'copy'
+
+  insertAtCursor: (insertValue) ->
+    log insertAtCursor: {insertValue}
+    # //IE support
+    # if (document.selection) {
+    #     @domElement.focus();
+    #     sel = document.selection.createRange();
+    #     sel.text = insertValue;
+    # }
+    # //MOZILLA and others
+    if @domElement.selectionStart || @domElement.selectionStart == '0'
+      {value, selectionStart, selectionEnd} = @domElement
+      log insertAtCursor: {value, selectionStart, selectionEnd,insertValue}
+      @domElement.value =
+        value.substring(0, selectionStart) + insertValue +
+        value.substring selectionEnd, value.length
+      @domElement.selectionEnd = @domElement.selectionStart = selectionStart + insertValue.length
+    else
+      @domElement.value += insertValue
+    @checkIfValueChanged()


Start dev server after first build, for clearer log output

--- development/index.coffee
+++ development/index.coffee
@@ -4,6 +4,6 @@

 module.exports = (project_directory) ->

-    build_directory = runCompilation(project_directory)
-    startServer('localhost', 5000, build_directory)
+    build_directory = runCompilation project_directory, (files) ->
+        startServer('localhost', 5000, build_directory)


Usa siteName default em branco

Usa siteName default em branco

--- src/coffee/portal-shipping-calculator.coffee
+++ src/coffee/portal-shipping-calculator.coffee
@@ -97,7 +97,7 @@
 		requiredPostalCode: 'O CEP deve ser informado.'
 		invalidPostalCode: 'CEP inválido.'
 		requiredQuantity: 'É necessário informar a quantidade do mesmo Produto.'
-		siteName: 'Vtex.Commerce.Web.CommerceContext.Current.WebSite.Name'
+		siteName: ''
 		close: 'Fechar'

 # COMPATIBILIDADE (DEPRECATED)


Loader: detect script path to load ammo.js relative to it.

--- engine/loader.coffee
+++ engine/loader.coffee
@@ -13,6 +13,10 @@
 {fetch_objects} = require './fetch_assets.coffee'
 {Texture} = require './texture.coffee'

+if process.browser
+    # for loading ammo.js relative to the output .js
+    scripts = document.querySelectorAll 'script'
+    current_script_path = scripts[scripts.length-1].src?.split('/')[...-1].join('/') or ''

 load_scene = (name, filter, use_physics, context) ->
     scene = context.scenes[name]
@@ -23,7 +27,7 @@
     url = "#{context.MYOU_PARAMS.data_dir}/scenes/#{name}/all.json"
     return fetch(url).then (response) ->
         if not response.ok
-            return Promise.reject "Scene '#{name}' could not be loaded from URL #{url[...-8]}"
+            return Promise.reject "Scene '#{name}' could not be loaded from URL '#{url}' with error '#{response.status} #{response.statusText}'"
         return response.json()
     .then (data)=>
         if filter
@@ -344,7 +348,7 @@
             script.async = true

             if process.browser
-                physics_engine_url = require("file-loader?name=/libs/ammo.asm.js!./libs/ammo.asm.js")
+                physics_engine_url = current_script_path + '/' + require("file-loader?name=/libs/ammo.asm.js!./libs/ammo.asm.js")
             else
                 dirname =  __dirname.replace(/\\/g, '/')
                 physics_engine_url = 'file://' + dirname + "/libs/ammo.asm.js"


Use more logical way of empty state

Use more logical way of empty state

--- core/app/backbone/views/react_feed_activities.coffee
+++ core/app/backbone/views/react_feed_activities.coffee
@@ -23,7 +23,7 @@
   componentDidUpdate: -> @checkScrolledPosition()

   componentWillMount: ->
-    if !@model().length
+    if @model().length == 0
       @model().loadMore()

   componentWillUnmount: ->


Laura is now a bike part 🚲

Laura is now a bike part 🚲

--- scripts/ayp.coffee
+++ scripts/ayp.coffee
@@ -90,8 +90,8 @@
     # I don't even understand this one
     name = 'cody_'

-  if /laura/i.test(name)
-    # Some kind of laura is one kind of laura
+  if /laura/i.test(name) or /kickstand/i.test(name)
+    # Some kind of laura is one kind of laura. Now a deprercated bike component
     name = 'laura'

   if /arbo/i.test(name)


Small code style improvement.

Small code style improvement.

--- app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee
+++ app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee
@@ -154,7 +154,7 @@

     # remove ignored items from collection
     if @ignoreObjectIDs
-      objects = _.filter(objects, (item) ->
+      objects = _.filter( objects, (item) ->
         return if item.id is 1
         return item
       )


fixed Hound linter comments

fixed Hound linter comments

--- app/assets/javascripts/frontend/custom_questions/ongoing_date_duration.js.coffee
+++ app/assets/javascripts/frontend/custom_questions/ongoing_date_duration.js.coffee
@@ -1,4 +1,4 @@
-window.ongoingDateDuration = () ->
+window.ongoingDateDuration = ->
   $(document).on "change", ".date-ongoing input", ->
     date_end_inputs = $(this).closest(".validate-date-start-end").find(".validate-date-end input")
     if $(this).is(":checked")


Animate chart container drawing

Animate chart container drawing

--- app/assets/javascripts/workbench/workbench/views/datastream/chart_view.js.coffee
+++ app/assets/javascripts/workbench/workbench/views/datastream/chart_view.js.coffee
@@ -2,6 +2,7 @@
   initialize: ->

   render: ->
+    @$el.animate(height: 400).promise().done(=>
       @chart = @$el.GeocensChart
         datastream: @model.object

@@ -31,5 +32,6 @@
               type: 'all'
               text: "All"
             }]
+    )

     this


Make sure that we properly unsubscribe from any outdated portions of a keypath.

--- src/keypath_observer.coffee
+++ src/keypath_observer.coffee
@@ -15,15 +15,15 @@
     current = @view.adapters[@root.interface].read @view.models, @root.path

     for token, index in @tokens
-      next = @view.adapters[token.interface].read current, token.path
-
       if @objectPath[index]?
-        if next isnt @objectPath[index]
-          @view.adapters[token.interface].unsubscribe current, token.path, @update
-          @view.adapters[token.interface].subscribe next, token.path, @update
+        if current isnt prev = @objectPath[index]
+          @view.adapters[token.interface].unsubscribe prev, token.path, @update
+          @view.adapters[token.interface].subscribe current, token.path, @update
+          @objectPath[index] = current
       else
         @view.adapters[token.interface].subscribe current, token.path, @update
+        @objectPath[index] = current

-      current = next
+      current = @view.adapters[token.interface].read current, token.path

     current


Added RequestsAll parser

Added RequestsAll parser

--- SingularityUI/app/collections/RequestsAll.coffee
+++ SingularityUI/app/collections/RequestsAll.coffee
@@ -1,10 +1,24 @@
-Requests = require "./Requests"
-
 RequestsActive = require "./RequestsActive"

+class RequestsAll extends RequestsActive
+
+    url: "#{ config.apiRoot }/requests",
+    comparator: "timestamp"
+
+    # RequestsActive & its subclasses share a parse(), while RequestsCleaning and RequestsPending have
+    #    their own. When fetching all Requests, this parse() uses the appropriate class' parse() on each request
+    parse: (requests) =>
+        _.each requests, (request, i) =>
+            if request.request.cleanupType?
+                parsingClass = app.collections.requestsCleaning
+            else if request.request.requestDeployState? and request.request.requestDeployState.pendingDeploy?
+                parsingClass = app.collections.requestsPending
+            else
+                parsingClass = app.collections.requestsActive
+
+            parsed = parsingClass.parse([request])
+            requests[i] = parsed[0]

-class RequestsAll extends RequestsActive
-
-	url: "#{ config.apiRoot }/requests"
+        requests

 module.exports = RequestsAll


futzing w inspector ui

futzing w inspector ui

--- src/javascript/inspector/inspector_ui.coffee
+++ src/javascript/inspector/inspector_ui.coffee
@@ -4,6 +4,8 @@
 List = Immutable.List
 Set = Immutable.Set
 imm = Immutable.fromJS
+
+{div,span,table,tbody,td,tr} = React.DOM

 ComponentSearchBox = require './component_search_box'

@@ -21,24 +23,32 @@

   render: ->
     folder = if @state.foldOpen
-        React.DOM.span {className: 'inspector-folder open'}, "- "
+        span {className: 'inspector-folder open'}, "- "
       else
-        React.DOM.span {className: 'inspector-folder closed'}, "+ "
+        span {className: 'inspector-folder closed'}, "+ "

-    header = React.DOM.div {className: "inspector-header", onClick: @headerClicked}, folder, "Entity Inspector"
+    header = div {className: "inspector-header", onClick: @headerClicked}, folder, "Entity Inspector"

-    views = if @state.foldOpen
-      List([
-        React.DOM.div {className: 'entities'},
+    views = []
+    if @state.foldOpen
+      countComps = (sum,comps) -> sum + comps.size
+      views.push(
+        div {className: 'entitiesSummary'},
+          "#{@props.entities.size} entities, #{@props.entities.valueSeq().reduce(countComps, 0)} components"
+      )
+      views.push(
+        div {className: 'entities'},
           @props.entities.map((components,eid) =>
             React.createElement Entity, {eid: eid, components: components, key: eid, inspectorConfig: @props.inspectorConfig}
           ).toList()
+      )
+
+    if @state.showSearchBox
+      views.push(
         React.createElement ComponentSearchBox, {key: 'component-search-box', entityStore: @props.entityStore}
-      ])
-    else
-      List()
+      )

-    React.DOM.div {className: 'component-inspector'},
+    div {className: 'component-inspector'},
       header,
       views

@@ -56,16 +66,16 @@

   render: ->
     folder = if @state.foldOpen
-        React.DOM.span {className: 'entity-folder open'}, "[ - ] "
+        span {className: 'entity-folder open'}, "[ - ] "
       else
-        React.DOM.span {className: 'entity-folder closed'}, "[ + ] "
+        span {className: 'entity-folder closed'}, "[ + ] "

     nameLabel = "Entity #{@props.eid}"
     @props.components.forEach (comp,cid) =>
       if comp.get('type') == 'name'
         nameLabel = comp.get('name') + " (#{@props.eid})"

-    header = React.DOM.div {className: "entity-header", onClick: @headerClicked},
+    header = div {className: "entity-header", onClick: @headerClicked},
       folder
       nameLabel

@@ -77,7 +87,7 @@
       List()

-    React.DOM.div {className: 'entity'},
+    div {className: 'entity'},
       header,
       componentViews

@@ -102,16 +112,16 @@
     comp = @props.component

     folder = if @state.foldOpen
-        React.DOM.span {className: 'component-folder open'}, "[ - ] "
+        span {className: 'component-folder open'}, "[ - ] "
       else
-        React.DOM.span {className: 'component-folder closed'}, "[ + ] "
+        span {className: 'component-folder closed'}, "[ + ] "

-    header = React.DOM.div {className: "component-header", onClick: @headerClicked},
+    header = div {className: "component-header", onClick: @headerClicked},
       folder
-      React.DOM.span {className: 'component-type'},
+      span {className: 'component-type'},
         comp.get('type')
       " "
-      React.DOM.span {className: 'component-cid'},
+      span {className: 'component-cid'},
         comp.get('cid')

     if @state.foldOpen
@@ -120,30 +130,30 @@
         React.createElement PropRow, {key: key, name: key, value: value}
       ).toList()

-      props = React.DOM.table {className: 'component-props'},
-        React.DOM.tbody null,
+      props = table {className: 'component-props'},
+        tbody null,
         rows

-      React.DOM.div {className: 'component'},
+      div {className: 'component'},
         header,
         props

     else
-      React.DOM.div {className: 'component'},
+      div {className: 'component'},
         header

 PropRow = React.createClass
   displayName: 'PropRow'
   render: ->
-    React.DOM.tr null,
-      React.DOM.td {className:'prop-name'}, @props.name
+    tr null,
+      td {className:'prop-name'}, @props.name
       React.createElement PropValueCell, {value: @props.value}

 PropValueCell = React.createClass
   displayName: 'PropValueCell'
   render: ->
     val = if @props.value? then @props.value.toString() else "?"
-    React.DOM.td {className:'prop-value'}, val
+    td {className:'prop-value'}, val

 module.exports = InspectorUI


Fix typo.

Fix typo.

--- nls/root/strings.coffee
+++ nls/root/strings.coffee
@@ -17,7 +17,7 @@
   feedback: 'Palaute'
   blankSlate:
     theTitle: "Tämä on ihan hyvä reittiopas."
-    thePitch: "Syötä lähtöpisteesi ja määränpääsi ylläoleviin kenttiin,ja neuvomme miten pääset parhaiten perille."
+    thePitch: "Syötä lähtöpisteesi ja määränpääsi ylläoleviin kenttiin, ja neuvomme miten pääset parhaiten perille."
     example: "Esimerkki"
     theRoute: "Mannerheimintie 15:sta Roihuvuoren Kirjastoon"
     theCoverage: "Palvelu kattaa Helsingin, Espoon, Vantaan, Kauniaisten, Keravan ja Kirkkonummen joukkoliikenteen."


Add scoring time to comparison table. PP-73

--- client/src/scripts/scoring-view.coffee
+++ client/src/scripts/scoring-view.coffee
@@ -205,6 +205,7 @@
         ]
       ]
       errorRow = [ th 'Error' ]
+      durationRow = [ th 'Time' ]
       aucRow = [ th 'AUC' ]
       thresholdCriterionRow = [ th 'Threshold Criterion' ]
       thresholdRow = [ thIndent 'Threshold' ]
@@ -245,6 +246,7 @@
         rocCurveRow.push td 'Loading...', "roc-#{scoreIndex}"
         inputParametersRow.push td createParameterTable parameters: inputParamsByScoreIndex[scoreIndex]
         errorRow.push td (format4f metrics.error_measure) + errorBadge #TODO change to bootstrap badge
+        durationRow.push td "#{metrics.duration_in_ms} ms"
         aucRow.push td format4f auc.AUC
         thresholdCriterionRow.push td head auc.threshold_criteria
         thresholdRow.push td head auc.threshold_for_criteria
@@ -285,6 +287,7 @@
         tr rocCurveRow
         tr inputParametersRow
         tr errorRow
+        tr durationRow
         tr aucRow
         tr thresholdCriterionRow
         tr thresholdRow


Fixes mobile page rendering. No clue why.

--- _source/client/templates/components/modal.coffee
+++ _source/client/templates/components/modal.coffee
@@ -87,5 +87,9 @@
           opacity: 1
         ,
           duration: 250
-          complete: (elements) ->
-            $(node).remove()
+
+      # fade out background
+      $(node).velocity "fadeOut",
+        duration: 250
+        complete: (elements) ->
+          $(node).remove()


Fix #75.

Fix #75.

--- annotran/static/scripts/annotator/sidebar.coffee
+++ annotran/static/scripts/annotator/sidebar.coffee
@@ -258,6 +258,15 @@
       if isClaimed
         break

+    if ((selection_box.bottom == 0 &&
+        selection_box.height == 0 &&
+        selection_box.left == 0 &&
+        selection_box.right == 0 &&
+        selection_box.top == 0 &&
+        selection_box.width == 0) || (range.start.data == ''))
+      alert("You cannot create a new translation here. No text selected.")
+      return
+
     if isClaimed
       alert("You cannot create a new translation here since the currently selected region is already translated by you. Please edit or delete your existing translation instead.")
     else


bugfix: usernameAvailable should actually check the availability of the JName

--- workers/social/lib/social/models/user.coffee
+++ workers/social/lib/social/models/user.coffee
@@ -499,18 +499,20 @@
         callback null, yes

   @usernameAvailable = (username, callback)->
+    JName = require './name'
+
     username += ''
-    r =
+    res =
       kodingUser   : no
       forbidden    : yes

-    @count {username}, (err, count)=>
+    JName.count { name: username }, (err, count)=>
       if err or username.length < 4 or username.length > 25
-        callback err, r
-      else
-        r.kodingUser = if count is 1 then yes else no
-        r.forbidden = if username in @bannedUserList then yes else no
-        callback null, r
+        callback err, res
+      else
+        res.kodingUser = if count is 1 then yes else no
+        res.forbidden = if username in @bannedUserList then yes else no
+        callback null, res

   fetchContextualAccount:(context, rest..., callback)->
     Relationship.one {


Add language-babel to atom

Add language-babel to atom

Fixes optional-chainer ?. operator support
but breaks syntax highlighting so disabled

--- .config/atom/config.cson
+++ .config/atom/config.cson
@@ -18,6 +18,7 @@
       "spell-check"
       "symbols-view"
       "angularjs"
+      "language-babel"
     ]
     packagesWithKeymapsDisabled: [
       "refactor"
@@ -42,6 +43,8 @@
   "highlight-selected": {}
   hyperclick:
     linuxTriggerKeys: "shiftKey,ctrlKey"
+  "language-babel":
+    disableWhenNoBabelrcFileInPath: false
   linter:
     ignoreGlob: "{**/dist/*.js,**/build/*.js,**/vendor/*.js,**/scripts/web-server.js,**/service-worker.js}"
     lintOnChange: false


determine which staging servers to use

determine which staging servers to use

--- server/stgr.coffee
+++ server/stgr.coffee
@@ -31,18 +31,12 @@
 serverResults = {}
 lastChange    = 0
 serverData    = {}
-serverList    = [
-  'stage01.thrillist.com'
-  'stage02.thrillist.com'
-  'stage03.thrillist.com'
-  'stage04.thrillist.com'
-  'stage01.supercompressor.com'
-  'stage02.supercompressor.com'
-  'stage01.jackthreads.com'
-  'stage02.jackthreads.com'
-  'stage03.jackthreads.com'
-  'stage05.jackthreads.com'
-  'stage06.jackthreads.com'
+serverList    = []
+propertyList  = [
+  'thrillist'
+  'supercompressor'
+  'jackthreads'
+  'thrillistmediagroup'
 ]

 ###
@@ -61,8 +55,8 @@
   # init server
   do initServer

-  # init query
-  do initQuery
+  # init server list, then init server query
+  initServerList initQuery

 ###
 init server
@@ -156,6 +150,59 @@
     res.header 'Access-Control-Allow-Origin', '*'
     res.json responseObj

+###
+set interval to check on available servers
+###
+initServerList = (callback = ->) ->
+  t = setInterval ->
+    do collateServers
+  , 21600000 # update server list every 6 hours
+
+  collateServers callback
+
+###
+create list of available servers
+###
+collateServers = (callback = ->) ->
+  console.info 'determining which staging servers are in play'
+
+  possibleServers = 100
+  returnedResults = 0
+  foundServers    = []
+
+  _.each propertyList, (property) ->
+    _.times possibleServers, (n) ->
+      n++
+
+      if n.toString().length is 1 then n = '0' + n
+
+      pingServer 'stage' + n + '.' + property + '.com', (validServer) ->
+        returnedResults++
+
+        foundServers.push validServer if validServer
+
+        if returnedResults is possibleServers * propertyList.length
+          serverList = foundServers
+
+          do callback
+
+###
+check for ssh access to server
+###
+pingServer = (server, callback) ->
+  conn = new SSH()
+
+  conn.on 'ready', ->
+    callback server
+
+  conn.on 'error', (error) ->
+    callback false
+
+  conn.connect
+    host: server
+    port: 22
+    username: 'leeroy'
+    privateKey: file.readFileSync 'leeroy_id_rsa.pem'

 ###
 init query


Add CSON snippet to insert a newline-snarf hack

--- .config/snippets.cson
+++ .config/snippets.cson
@@ -79,6 +79,9 @@
 	"Capturing Groups: End":
 		prefix: "end"
 		body: 'endCaptures:\n\t0: name: "$2"'
+	"Newline Snarf":
+		prefix: "nl"
+		body: 'begin: "\\\\\\\\\\\\\\\\$\\\\\\\\n"\nend: "^"'

 	# Symptoms of leaning toothpick syndrome:
 	"Escaped Backslash":


Fix edit button.

Fix edit button.

--- app/assets/javascripts/admin_shortcuts.js.coffee
+++ app/assets/javascripts/admin_shortcuts.js.coffee
@@ -113,6 +113,10 @@
       @modal.find(".modal-content").data("user", user_query)
       @modal.find(".modal-content").html(data)
       callback?()
+      @modal.on("shown", =>
+        $(document).off("focusin.modal")
+        @modal.off("shown")
+      )
       @modal.modal().css({
           width: 'auto',
           'margin-left': ->


Use OSM via HTTPS to prevent mixed-content-warnings, fixes #260

--- app/assets/javascripts/application/shifts.coffee
+++ app/assets/javascripts/application/shifts.coffee
@@ -7,7 +7,7 @@
     lat = mapContainer.data 'lat'
     long = mapContainer.data 'long'
     map = L.map(mapContainer.attr('id'), { scrollWheelZoom: false })
-    osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
+    osmUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
     osmAttrib = 'Map data © OpenStreetMap contributors'
     osm = new L.TileLayer(osmUrl, { minZoom: 8, maxZoom: 18, attribution: osmAttrib })
     map.setView(new L.LatLng(lat, long), 15)


now editing in translated environment also works

--- hyperbolic_tessellation_test_app.coffee
+++ hyperbolic_tessellation_test_app.coffee
@@ -265,10 +265,9 @@
   xyt = poincare2hyperblic xp, yp
   #inverse transform it...
   xyt = M.mulv (M.inv tfm), xyt
-  if xyt is null
-    #console.log "Outside of circle"
-  else
-    cell = xytFromCell xyt
+  if xyt isnt null
+    visibleCell = xytFromCell xyt
+    cell = eliminateFinalA appendRewrite(observer.center, node2array(visibleCell)), appendRewrite, tessellation.group.n
     #console.log showNode cell
     if cells.get(cell) isnt null
       cells.remove cell


fixed NPE

fixed NPE

--- app/assets/javascripts/monitoring/util.js.coffee
+++ app/assets/javascripts/monitoring/util.js.coffee
@@ -49,7 +49,7 @@
     opts.valueRange = [ 0, 100 ]
     opts.yRangePad = 1

-  else if matches = metric.get("range").match(/\.\./)
+  else if metric.get("range") && (matches = metric.get("range").match(/\.\./))
     # use y-axis range as given in metric info
     opts.valueRange = [ matches[1], matches[2] ]


Rename intervaFromFeature to intervalFromFeature

--- src/leaflet.timeline.coffee
+++ src/leaflet.timeline.coffee
@@ -70,15 +70,15 @@
     L.GeoJSON.prototype.initialize.call this, undefined, options
     L.extend @options, options
     @ranges = new IntervalTree()
-    if options.intervaFromFeature?
-      @intervaFromFeature = options.intervaFromFeature.bind(this)
+    if options.intervalFromFeature?
+      @intervalFromFeature = options.intervalFromFeature.bind(this)
     if options.addData?
       @addData = options.addData.bind(this)
     if options.doSetTime?
       @doSetTime = options.doSetTime.bind(this)
     @process timedGeoJSON if timedGeoJSON?

-  intervaFromFeature: (feature) ->
+  intervalFromFeature: (feature) ->
     start = ( new Date feature.properties.start ).getTime()
     end = ( new Date feature.properties.end ).getTime()
     return [start, end]
@@ -87,7 +87,7 @@
     earliestStart = Infinity
     latestEnd = -Infinity
     data.features.forEach (feature) =>
-      interval = @intervaFromFeature(feature)
+      interval = @intervalFromFeature(feature)
       @ranges.insert interval[0], interval[1], feature
       @times.push interval[0]
       @times.push interval[1]


Remove global findModeAnchorNode and false comments justifying it

--- content_scripts/vimium_frontend.coffee
+++ content_scripts/vimium_frontend.coffee
@@ -8,7 +8,6 @@
 window.findModeQuery = { rawQuery: "", matchCount: 0 }
 window.findMode = null
 window.findModeQueryHasResults = false
-findModeAnchorNode = null
 isShowingHelpDialog = false
 keyPort = null
 isEnabledForUrl = true
@@ -739,9 +738,6 @@
   if document.activeElement and DomUtils.isEditable document.activeElement
     document.activeElement.blur() unless DomUtils.isSelected document.activeElement

-  # we need to save the anchor node here because <esc> seems to nullify it, regardless of whether we do
-  # preventDefault()
-  findModeAnchorNode = document.getSelection().anchorNode
   result

 restoreDefaultSelectionHighlight = -> document.body.classList.remove("vimiumFindMode")
@@ -752,10 +748,10 @@
     link.focus() if link

 selectFoundInputElement = ->
-  # if the found text is in an input element, getSelection().anchorNode will be null, so we use activeElement
-  # instead. however, since the last focused element might not be the one currently pointed to by find (e.g.
-  # the current one might be disabled and therefore unable to receive focus), we use the approximate
-  # heuristic of checking that the last anchor node is an ancestor of our element.
+  # Since the last focused element might not be the one currently pointed to by find (e.g.  the current one
+  # might be disabled and therefore unable to receive focus), we use the approximate heuristic of checking
+  # that the last anchor node is an ancestor of our element.
+  findModeAnchorNode = document.getSelection().anchorNode
   if (findModeQueryHasResults && document.activeElement &&
       DomUtils.isSelectable(document.activeElement) &&
       DomUtils.isDOMDescendant(findModeAnchorNode, document.activeElement))


Remove debug log

Remove debug log

--- app/src/tasks/operations_consumption_task.coffee
+++ app/src/tasks/operations_consumption_task.coffee
@@ -18,11 +18,6 @@
       @stopIfNeccessary()
       _.defer -> ledger.app.emit 'wallet:operations:sync:done'

-  startIfNeccessary: ->
-    l "START", new Error().stack
-    super
-
-
   onStop: ->
     super


Fix mentions parsing

Fix mentions parsing

--- assets/javascripts/views/new_post_form.js.coffee
+++ assets/javascripts/views/new_post_form.js.coffee
@@ -120,10 +120,8 @@
     )
     delete data.mentions

-    for entity in (data.text?.match(/\^(\S+)/g) || [])
-      entity = entity.replace(/^\^/, '')
-      continue unless entity.length
-      entity = entity.replace(/^/, 'https://') unless entity.match(/^https?/)
+    for i in TentStatus.Helpers.extractUrlsWithIndices(data.text)
+      entity = i.url

       exists = false
       for m in mentions


Always show disabled docs list

Always show disabled docs list

--- assets/javascripts/views/sidebar/doc_list.coffee
+++ assets/javascripts/views/sidebar/doc_list.coffee
@@ -36,7 +36,7 @@

   render: =>
     @html @tmpl('sidebarDoc', app.docs.all())
-    @renderDisabled() unless app.isSingleDoc() or app.settings.hasDocs()
+    @renderDisabled() unless app.isSingleDoc()
     @refreshElements()
     return


Insert discontinuous patches into rBush seperately

--- bokehjs/src/coffee/renderer/glyph/patches.coffee
+++ bokehjs/src/coffee/renderer/glyph/patches.coffee
@@ -9,15 +9,34 @@
     index = rbush()
     pts = []
     for i in [0...@xs.length]
-      xs = (x for x in @xs[i] when not _.isNaN(x))
-      ys = (y for y in @ys[i] when not _.isNaN(y))
-      if xs.length == 0
-        continue
-      pts.push([
-        _.min(xs), _.min(ys),
-        _.max(xs), _.max(ys),
-        {'i': i}
-      ])
+
+      xs = @xs[i]
+      ys = @ys[i]
+
+      while xs.length > 0
+
+        xs_nan_index = _.findLastIndex(xs, (x) ->  _.isNaN(x))
+        ys_nan_index = _.findLastIndex(ys, (y) ->  _.isNaN(y))
+
+        if xs_nan_index >= 0
+          xs_loop = xs.splice(xs_nan_index)
+        else
+          xs_loop = xs
+          xs = []
+
+        if ys_nan_index >= 0
+          ys_loop = ys.splice(ys_nan_index)
+        else
+          ys_loop = ys
+          ys = []
+
+        xs_push = (x for x in xs_loop when not _.isNaN(x))
+        ys_push = (y for y in ys_loop when not _.isNaN(y))
+        pts.push([
+          _.min(xs_push), _.min(ys_push),
+          _.max(xs_push), _.max(ys_push),
+          {'i': i}
+        ])
     index.load(pts)
     return index

@@ -114,4 +133,4 @@

 module.exports =
   Model: Patches
-  View: PatchesView+  View: PatchesView


Fixed decimal transaction [completed:42]

--- app/assets/javascripts/app/transaction.js.coffee
+++ app/assets/javascripts/app/transaction.js.coffee
@@ -340,6 +340,7 @@
 # View for the template
 class ExchangeRateDialog extends Backbone.View
   el: $("#exchange_rate")
+  # initialize
   initialize:->
     self = @
     @label = $('label[for=transaction_currency_id]')
@@ -376,9 +377,6 @@
       "", @model.get("default_symbol"), " ", _b.ntc(@model.get("exchange_rate"), 4), "",
       ' editar tipo de cambio']
       @label.find("span.rate_details").html(html.join(""))
-
-
-
   # Change in exchange rate
   setExchange: ->
     rate = ($(@el).find("#exchange_rate").val() * 1).round(4)
@@ -389,6 +387,10 @@
     @el.find("span.currency_symbol").html(@model.get("currency_symbol"))
     @el.dialog("open")
   closeDialog: ->
+    unless $("#exchange_rate").val().match(/^\d+(\.\d+)?$/)
+      alert("Debe ingresar un número seperado por (.) para los decimales")
+      return false
+
     @.setExchange()
     @el.dialog("close")


Changed how date gets cleared

Changed how date gets cleared

--- app/assets/javascripts/due_date_select.js.coffee
+++ app/assets/javascripts/due_date_select.js.coffee
@@ -13,8 +13,7 @@

     $('.js-clear-due-date').on 'click', (e) ->
       e.preventDefault()
-      $dueDate.val('')
-      $datePicker.datepicker('setDate', '')
+      $.datepicker._clearDate($datePicker)

     # Issuable sidebar
     $loading = $('.js-issuable-update .due_date')


Oh for five six

Oh for five six

--- app/assets/javascripts/exo/mixins/form.js.coffee
+++ app/assets/javascripts/exo/mixins/form.js.coffee
@@ -1,4 +1,4 @@
-Exo.View.registerMixin("form", ->, {
+Exo.View.registerMixin("form", (->), {
   showErrors: (allErrors, message=false) ->
     for namespace, errors of allErrors
       for field, error of errors


limit upper bound

limit upper bound

--- app/assets/javascripts/monitoring/util.js.coffee
+++ app/assets/javascripts/monitoring/util.js.coffee
@@ -80,6 +80,13 @@
       else if end_diff > 100000
         startX = dMaxX
         endX = maxX
+
+        # don't send timestamps into the future
+        now = new Date().getTime()
+        if endX > now
+          endX = now
+        if endX - startX < 100000
+          startX = null

       return if startX == null


fix coffeescript warnings (semicolons)

fix coffeescript warnings (semicolons)

--- app/assets/javascripts/monitoring/util.js.coffee
+++ app/assets/javascripts/monitoring/util.js.coffee
@@ -62,8 +62,8 @@
   g._bixby_mode = "zoom"

   # set callbacks
-  xOptView = g.optionsViewForAxis_('x');
-  xvf = xOptView('valueFormatter');
+  xOptView = g.optionsViewForAxis_('x')
+  xvf = xOptView('valueFormatter')
   opts = {
     highlightCallback: (e, x, pts, row) ->
       date = xvf(x, xOptView, "", g) + ", " + sprintf("val = %0.2f%s", pts[0].yval, unit)
@@ -99,7 +99,7 @@
           g.updateOptions({ file: new_met.tuples() })

   }
-  g.updateOptions(opts);
+  g.updateOptions(opts)
   return g

@@ -138,7 +138,7 @@
 #         graph: graph
 #       });
 #       graph.render();
-#       $(s + " .footer").text(sprintf("Last Value: %0.2f", val.vals[val.vals.length-1].y));
+#       $(s + " .footer").text(sprintf("Last Value: %0.2f", val.vals[val.vals.length-1].y))


FCランプがNになる不具合を修正

FCランプがNになる不具合を修正

--- app/assets/javascripts/stores/score_store.coffee
+++ app/assets/javascripts/stores/score_store.coffee
@@ -18,7 +18,7 @@
     threshold = if type is 'clear' then 4 else 2
     remain = 0
     for id, _ of SheetStore.get()
-      score = scores[id]
+      score = objectCopy scores[id]
       score ||= {}
       score.state ||= 7
       remain++ if threshold < score.state


Starts Header and Main regions

Starts Header and Main regions

--- app/assets/javascripts/backbone/app.js.coffee
+++ app/assets/javascripts/backbone/app.js.coffee
@@ -8,7 +8,10 @@
     footerRegion  : "#footer-region"

   App.addInitializer ->
+    App.module("HeaderApp").start()
+    App.module("MainApp").start()
     App.module("FooterApp").start()
+

   App.on "start", (options) ->
     if Backbone.history


handle focus , selected on click on graf--figure (img/caption)

--- app/assets/javascripts/dante/editor.js.coffee
+++ app/assets/javascripts/dante/editor.js.coffee
@@ -10,7 +10,8 @@
     "keydown" : "handleKeyDown"
     "keyup"   : "handleKeyUp"
     "paste"   : "handlePaste"
-    "click .graf--figure" : "handleGrafFigureSelect"
+    "click .graf--figure img" : "handleGrafFigureSelectImg"
+    "click figcaption"   : "handleGrafFigureSelectCaption"
     "dblclick" : "handleDblclick"
     "dragstart": "handleDrag"
     "drop"    : "handleDrag"
@@ -265,10 +266,20 @@
     $(".graf--first").html(@title_placeholder)
     $(".graf--last").html(@body_placeholder)

-  handleGrafFigureSelect: (ev)->
+  handleGrafFigureSelectImg: (ev)->
+    utils.log "FIGURE SELECT"
     element = ev.currentTarget
     @markAsSelected( element )
-    @setRangeAt( $(element).find('.imageCaption')[0] )
+    $(element).parent().addClass("is-selected is-mediaFocused")
+    @selection().removeAllRanges()
+
+  handleGrafFigureSelectCaption: (ev)->
+    utils.log "FIGCAPTION"
+    element = ev.currentTarget
+    $(element).parent().removeClass("is-mediaFocused")
+    #return false
+    #@setRangeAt( $(element).find('.imageCaption')[0] )
+

   handleBlur: (ev)=>
     #hide menu only if is not in use
@@ -281,8 +292,8 @@
   handleMouseUp: (ev)=>
     utils.log "MOUSE UP"
     anchor_node = @getNode()
-    utils.log anchor_node
-    utils.log ev.currentTarget
+    #utils.log anchor_node
+    #utils.log ev.currentTarget

     return if _.isNull(anchor_node)

@@ -668,7 +679,9 @@

     #hides tooltip if anchor_node text is empty
     if anchor_node
-      @tooltip_view.hide() unless _.isEmpty($(anchor_node).text())
+      unless _.isEmpty($(anchor_node).text())
+        @tooltip_view.hide()
+        $(anchor_node).removeClass("graf--empty")

   handleKeyUp: (e , node)->
     utils.log "KEYUP"
@@ -713,10 +726,6 @@
     if _.contains([37,38,39,40], e.which)
       @handleArrow(e)
       #return false
-
-    #remove graf--empty if anchor_node text is empty
-    if anchor_node
-      $(anchor_node).removeClass("graf--empty") unless _.isEmpty($(anchor_node).text())

   #TODO: Separate in little functions
   handleLineBreakWith: (element_type, from_element)->
@@ -748,8 +757,19 @@
     $(@el).find(".is-selected").removeClass("is-mediaFocused is-selected")
     $(element).addClass("is-selected")

+    ###
     if $(element).prop("tagName").toLowerCase() is "figure"
       $(element).addClass("is-mediaFocused")
+      n = utils.getNode()
+      utils.log n
+
+      n = utils.getNode()
+      utils.log n
+      if _.isUndefined n
+        $(element).addClass("is-mediaFocused")
+      else if $(n).prop("tagName").toLowerCase() is "figcaption"
+        $(element).removeClass("is-mediaFocused")
+    ###

     $(element).find(".defaultValue").remove()
     #set reached top if element is first!


Add mising relation in Track

Add mising relation in Track

--- app/assets/javascripts/models/track.js.coffee
+++ app/assets/javascripts/models/track.js.coffee
@@ -1,2 +1,4 @@
 Yossarian.Track = DS.Model.extend
   name: DS.attr 'string'
+
+  recordings: DS.hasMany 'recording'


added orchestrations

added orchestrations

--- src/middleware/stats.coffee
+++ src/middleware/stats.coffee
@@ -26,16 +26,17 @@

         if route.orchestrations?
           for orchestration in route.orchestrations
+            orchestrationStatus = orchestration.status
             sdc.increment domain + '.Channels.' + ctx.authorisedChannel._id + '.nonPrimaryRoutes.' + route.name + '.orchestrations.' + orchestration.name
-            sdc.increment domain + '.Channels.' + ctx.authorisedChannel._id + '.nonPrimaryRoutes.' + route.name + '.orchestrations.' + orchestration.name + '.StatusCodes.' + orchestration.Status
+            sdc.increment domain + '.Channels.' + ctx.authorisedChannel._id + '.nonPrimaryRoutes.' + route.name + '.orchestrations.' + orchestration.name + '.StatusCodes.' + orchestrationStatus
             sdc.increment domain + '.Channels.' + ctx.authorisedChannel._id + '.nonPrimaryRoutes.' + route.name + '.StatusCodes.' + route.response.status + '.orchestrations.' + orchestration.name
-            sdc.increment domain + '.Channels.' + ctx.authorisedChannel._id + '.nonPrimaryRoutes.' + route.name + '.StatusCodes.' + route.response.status + '.orchestrations.' + orchestration.name + '.StatusCodes.' + orchestration.Status
+            sdc.increment domain + '.Channels.' + ctx.authorisedChannel._id + '.nonPrimaryRoutes.' + route.name + '.StatusCodes.' + route.response.status + '.orchestrations.' + orchestration.name + '.StatusCodes.' + orchestrationStatus

     if ctx.mediatorResponse?
       if ctx.mediatorResponse.orchestrations?
         for orchestration in ctx.mediatorResponse.orchestrations
-          orchestrationStatus = orchestration.Status
+          orchestrationStatus = orchestration.status
           sdc.increment domain + '.Channels.' + ctx.authorisedChannel._id + '.orchestrations.' + orchestration.name
           sdc.increment domain + '.Channels.' + ctx.authorisedChannel._id + '.orchestrations.' + orchestration.name + '.StatusCodes.' + orchestrationStatus
           sdc.increment domain + '.Channels.' + ctx.authorisedChannel._id + '.Statuses.' + transactionStatus + '.orchestrations.' + orchestration.name
@@ -63,7 +64,7 @@
         if route.orchestrations?
           for orchestration in route.orchestrations
             orchestratrionDuration = orchestration.response.timestamp - orchestration.request.timestamp
-            orchestrationStatus = orchestration.Status
+            orchestrationStatus = orchestration.status
             sdc.timing domain + '.Channels.' + ctx.authorisedChannel._id + '.nonPrimaryRoutes.' + route.name + '.orchestrations.' + orchestration.name, orchestratrionDuration
             sdc.timing domain + '.Channels.' + ctx.authorisedChannel._id + '.nonPrimaryRoutes.' + route.name + '.orchestrations.' + orchestration.name + '.StatusCodes.' + orchestrationStatus , orchestratrionDuration
             sdc.timing domain + '.Channels.' + ctx.authorisedChannel._id + '.nonPrimaryRoutes.' + route.name + '.StatusCodes' + route.response.status + '.orchestrations.' + orchestration.name, orchestratrionDuration


Use Map & Set instead of Objects in getChangedFiles.

--- deployment/getChangedFiles.coffee
+++ deployment/getChangedFiles.coffee
@@ -59,19 +59,19 @@
             return not key.match(root_prefix_exp)?
         return false

-    local_map = {}
-    remote_map = {}
+    local_map = new Map()
+    remote_map = new Set()
     local_files.forEach (f) ->
         key = f.replace(build_directory, '').substring(1)
         unless _isIgnorable(key)
-            local_map[key] = {
+            local_map.set(key, {
                 local_path: f
                 key: key
-            }
+            })

     if options.no_delete
         callback(
-            changed: Object.values(local_map).map (v) -> { local: v, remote: null }
+            changed: Array.from(local_map.values()).map (v) -> { local: v, remote: null }
             deleted: []
             unchanged: []
         )
@@ -90,11 +90,11 @@

             # Ignore files that don't exist locally when deleting of remote
             # files is disabled.
-            if options.no_delete and not local_map[f.Key]
+            if options.no_delete and not local_map.get(f.Key)
                 return

-            remote_map[f.Key] = true
-            unless local_map[f.Key]?
+            remote_map.add(f.Key)
+            unless local_map.get(f.Key)?
                 # Files that don't exist locally and need to be deleted from
                 # the remote deployment.
                 deleted.push
@@ -104,11 +104,11 @@
                 # Files that exist locally and remotely and need to be checked
                 # for sameness.
                 unknown.push
-                    local: local_map[f.Key]
+                    local: local_map.get(f.Key)
                     remote: f

         for k,v of local_map
-            unless remote_map[k]
+            unless remote_map.has(k)
                 # Files that exist locally but not remotely and definitely need
                 # to be uploaded.
                 changed.push


Fix when the button gets added

Fix when the button gets added

--- src/popout_for_youtube.coffee
+++ src/popout_for_youtube.coffee
@@ -114,8 +114,7 @@
     , 100

   videoChanged: ->
-    newId = @getVideoId()
-    !@video || !@video.node || !@video.node.src || newId != @previousVideoId
+    @getVideoId() != @previousVideoId

   getVideoId: ->
     new URLSearchParams(document.location.search.substring(1)).get('v')


Dock: question mark icon class updated

Dock: question mark icon class updated

--- client/Main/avatararea/avatarareaiconmenu.coffee
+++ client/Main/avatararea/avatarareaiconmenu.coffee
@@ -6,8 +6,11 @@

     @setClass "account-menu"

-    @helpIcon    = new AvatarAreaIconLink
+    @helpIcon    = new CustomLinkView
+      title      : ''
       cssClass   : "help acc-dropdown-icon"
+      icon       :
+        cssClass : 'icon'
       attributes :
         title    : 'Help'
         href     : 'http://learn.koding.com'


main controller: put cookie-polling back

This was commented out and accidentally committed.  Put it back.

--- client/Main/maincontroller/maincontroller.coffee
+++ client/Main/maincontroller/maincontroller.coffee
@@ -123,29 +123,29 @@
         window.removeEventListener 'beforeunload', wc.bound 'beforeUnload'
         location.reload()

-    # # async clientId change checking procedures causes
-    # # race conditions between window reloading and post-login callbacks
-    # @utils.repeat 3000, do (cookie = $.cookie 'clientId') => =>
-    #   cookieExists = cookie?
-    #   cookieMatches = cookie is ($.cookie 'clientId')
-    #   cookie = $.cookie 'clientId'
-    #   if cookieExists and not cookieMatches
-    #     return @isLoggingIn off  if @isLoggingIn() is on
-
-    #     window.removeEventListener 'beforeunload', wc.bound 'beforeUnload'
-    #     @emit "clientIdChanged"
-
-    #     # window location path is set to last route to ensure visitor is not
-    #     # redirected to another page
-    #     @utils.defer ->
-    #       firstRoute = KD.getSingleton("router").visitedRoutes.first
-
-    #      if firstRoute and /^\/Verify/.test firstRoute
-    #        firstRoute = "/"
-    #      if firstRoute and /^\/Reset/.test firstRoute
-    #        firstRoute = "/"
-
-    #       window.location.pathname = firstRoute or "/"
+    # async clientId change checking procedures causes
+    # race conditions between window reloading and post-login callbacks
+    @utils.repeat 3000, do (cookie = $.cookie 'clientId') => =>
+      cookieExists = cookie?
+      cookieMatches = cookie is ($.cookie 'clientId')
+      cookie = $.cookie 'clientId'
+      if cookieExists and not cookieMatches
+        return @isLoggingIn off  if @isLoggingIn() is on
+
+        window.removeEventListener 'beforeunload', wc.bound 'beforeUnload'
+        @emit "clientIdChanged"
+
+        # window location path is set to last route to ensure visitor is not
+        # redirected to another page
+        @utils.defer ->
+          firstRoute = KD.getSingleton("router").visitedRoutes.first
+
+         if firstRoute and /^\/Verify/.test firstRoute
+           firstRoute = "/"
+         if firstRoute and /^\/Reset/.test firstRoute
+           firstRoute = "/"
+
+          window.location.pathname = firstRoute or "/"

   setVisitor:(visitor)-> @visitor = visitor
   getVisitor: -> @visitor


Onboarding: Fixed showing prev button for last onboarding item.

--- client/Main/onboarding/onboardingitemview.coffee
+++ client/Main/onboarding/onboardingitemview.coffee
@@ -6,35 +6,55 @@

     super options, data

-    @nextButton        = new KDCustomHTMLView
-    @overlay           = new KDOverlayView
-      isRemovable      : no
-      parent           : "body"
+    @createElements()
+    @listenEvents()
+
+  createElements: ->
+    {hasPrev, hasNext, isLast} = @getOptions()
+    @prevButton    = new KDCustomHTMLView
+    @nextButton    = new KDCustomHTMLView
+    @doneButton    = new KDCustomHTMLView
+    @overlay       = new KDOverlayView
+      isRemovable  : no
+      parent       : "body"

     if hasPrev
-      @prevButton      = new KDButtonView
-        cssClass       : "prev-button solid medium light-gray"
-        title          : "PREV"
-        callback       : => @emit "NavigationRequested", "prev"
+      @prevButton  = new KDButtonView
+        cssClass   : "solid medium light-gray"
+        title      : "PREV"
+        callback   : => @emit "NavigationRequested", "prev"

     if hasNext
-      @nextButton      = new KDButtonView
-        cssClass       : "next-button solid medium green"
-        title          : "NEXT"
-        callback       : => @emit "NavigationRequested", "next"
+      @nextButton  = new KDButtonView
+        cssClass   : "solid medium green"
+        title      : "NEXT"
+        callback   : => @emit "NavigationRequested", "next"

+    if isLast
+      @doneButton  = new KDButtonView
+        cssClass   : "solid medium green"
+        title      : "DONE"
+        callback   : => @emit "OnboardingCompleted"
+
+  listenEvents: ->
     @on "NavigationRequested", (direction) =>
       @overlay.destroy()
       @destroy()
       @getDelegate().emit "NavigationRequested", direction, @getData()

+    @on "OnboardingCompleted", =>
+      @overlay.destroy()
+      @destroy()
+      @getDelegate().emit "OnboardingCompleted"
+
   pistachio: ->
-    {title, content} = @getData().partial
+    {title, content} = @getData()
     """

#{title}

#{content}

         {{> @prevButton}}
         {{> @nextButton}}
+        {{> @doneButton}}

     """


fix coffeelint error

fix coffeelint error

--- client/account/lib/accountsessionlistitem.coffee
+++ client/account/lib/accountsessionlistitem.coffee
@@ -46,7 +46,7 @@
     lastAccess = lastLoginDate or lastAccess

     if kookies.get('clientId') is clientId
-      cssClass = "active"
+      cssClass = 'active'
     @session = new kd.CustomHTMLView
       cssClass: 'group-name'
       partial: group


MachineStateModal: Added Unknown state and fixed Terminated state.

--- client/ide/views/modals/machinestatemodal.coffee
+++ client/ide/views/modals/machinestatemodal.coffee
@@ -42,7 +42,7 @@

     @createStateLabel()

-    if @state in ['Stopped', 'Running', 'NotInitialized', 'Terminated']
+    if @state in ['Stopped', 'Running', 'NotInitialized', 'Terminated', 'Unknown']
       @createStateButton()
     else if @state in [ 'Starting', 'Building', 'Stopping' ]
       @createLoading()
@@ -58,6 +58,7 @@
       Building       : 'is building now.'
       NotInitialized : 'is turned off.'
       Terminated     : 'is turned off.'
+      Unknown        : 'is turned off.'
       NotFound       : 'This machine does not exist.' # additional class level state to show a modal for unknown routes.

     @label     = new KDCustomHTMLView
@@ -107,7 +108,7 @@
     methodName   = 'start'
     nextState    = 'Starting'

-    if @state is 'NotInitialized'
+    if @state in [ 'NotInitialized', 'Terminated', 'Unknown' ]
       methodName = 'build'
       nextState  = 'Building'


Add spec for shorthand

Add spec for shorthand

--- spec/InPort.coffee
+++ spec/InPort.coffee
@@ -1,10 +1,14 @@
 chai = require 'chai' unless chai
 if typeof process isnt 'undefined' and process.execPath and process.execPath.indexOf('node') isnt -1
   inport = require '../src/lib/InPort'
+  outport = require '../src/lib/OutPort'
   socket = require '../src/lib/InternalSocket'
+  ports = require '../src/lib/Ports'
 else
   inport = require 'noflo/src/lib/InPort.js'
+  outport = require 'noflo/src/lib/OutPort'
   socket = require 'noflo/src/lib/InternalSocket.js'
+  ports = require 'noflo/src/lib/Ports'

 describe 'Inport Port', ->
   describe 'with default options', ->
@@ -150,3 +154,16 @@
       p.on 'data', cb
       s.send 'terrific'
       chai.expect(cb).not.toHaveBeenCalled()
+
+  describe 'with processing shorthand', ->
+    it 'should create a port with a callback', ->
+      s = new socket
+      ps = new ports
+        outPorts:
+          out: new outport
+      ps.add 'in', (packet, outPorts) ->
+        chai.expect(packet).toEqual 'some-data'
+        chai.assert outPorts.out instanceof outport
+      chai.assert ps.inPorts.in instanceof inport
+      ps.inPorts.in.attach s
+      s.send 'some-data'


Connections are only setup when tests are run

--- test/browser/subscribed.coffee
+++ test/browser/subscribed.coffee
@@ -5,9 +5,11 @@

 describe 'Subscribed Document', ->

-  connections =
-    alice: new Connection(new BCSocket)
-    bob:   new Connection(new BCSocket)
+  connections = {}
+
+  before ->
+    connections.alice = new Connection(new BCSocket)
+    connections.bob =   new Connection(new BCSocket)

   after ->
     for name, connection of connections


plot.coffee add min_size to nonserializable attributes

--- bokehjs/src/coffee/common/plot.coffee
+++ bokehjs/src/coffee/common/plot.coffee
@@ -536,7 +536,8 @@
   ]

   nonserializable_attribute_names: () ->
-    super().concat(['solver', 'above', 'below', 'left', 'right', 'canvas', 'tool_manager', 'frame'])
+    super().concat(['solver', 'above', 'below', 'left', 'right', 'canvas', 'tool_manager', 'frame',
+    'min_size'])

   defaults: ->
     return _.extend {}, super(), {


hub: ideas for monitoring the user query queue

--- src/smc-hub/postgres-user-query-queue.coffee
+++ src/smc-hub/postgres-user-query-queue.coffee
@@ -22,6 +22,16 @@
 # This is currently not used for anything except logging.
 TIME_HISTORY_LENGTH = 100

+# setup metrics
+metrics_recorder = require('./metrics-recorder')
+query_queue_exec = metrics_recorder.new_counter('query_queue_executed_total',
+                    'Executed queries and their status', ['status'])
+query_queue_duration = metrics_recorder.new_counter('query_queue_duration_seconds_total',
+                    'Total time it took to evaluate queries')
+query_queue_done = metrics_recorder.new_counter('query_queue_done_total',
+                    'Total number of evaluated queries')
+query_queue_count = metrics_recorder.new_gauge('queue_queue_count', 'Number of outstanding queries in the queue', ['client'])
+
 class exports.UserQueryQueue
     constructor: (opts) ->
         opts = defaults opts,
@@ -38,6 +48,7 @@
     destroy: =>
         delete @_do_query
         delete @_limit
+        delete @_timeout_ms
         delete @_dbg
         delete @_state

@@ -83,6 +94,7 @@
             # point in even trying; the client likely already gave up.
             opts.cb?("timeout")
             cb()
+            query_queue_exec.labels('timeout').inc()
             return

         @_dbg("_do_one_query(client_id='#{opts.client_id}') -- doing the query")
@@ -107,6 +119,7 @@
             orig_cb?(err, result)

         # Finally, do the query.
+        query_queue_exec.label('sent').inc()
         @_do_query(opts)

     _update: (state) =>
@@ -124,7 +137,10 @@
         tm = new Date()
         @_do_one_query opts, =>
             state.count -= 1
-            state.time_ms.push(new Date() - tm)
+            duration_ms = new Date() - tm
+            state.time_ms.push(duration_ms)
+            query_queue_duration.inc(duration_ms / 1000)
+            query_queue_done.inc(1)
             if state.time_ms.length > TIME_HISTORY_LENGTH
                 state.time_ms.shift()
             @_info(state)
@@ -139,4 +155,5 @@
         return s / v.length

     _info: (state) =>
+        query_queue_count.labels(state.client_id).set(state.count)
         @_dbg("client_id='#{state.client_id}': avg=#{@_avg(state)}ms, count=#{state.count}, queued.length=#{state.queue?.length}, sent=#{state.sent}")


Ensure @range is set before delegate call to prevent potential infinite loop

--- src/trix/observers/selection_observer.coffee
+++ src/trix/observers/selection_observer.coffee
@@ -29,8 +29,9 @@
   update: ->
     range = getRange()
     unless rangesAreEqual(range, @range)
-      @delegate?.selectionDidChange?(range, @range)
+      previousRange = @range
       @range = range
+      @delegate?.selectionDidChange?(range, previousRange)

   getRange = ->
     selection = window.getSelection()


updated to work with latest dashboard changes

--- src/ubret/spacewarp_viewer/initialize.coffee
+++ src/ubret/spacewarp_viewer/initialize.coffee
@@ -174,17 +174,18 @@
     )

   setBand: (band) =>
+    console.log 'setBand', band
     if band is 'gri'
       @wfits.drawColor('i', 'r', 'g')
     else
       # Compute the min/max of the image set
       unless @collection.hasExtent
-        @collection.hasExtent = true
         mins = @collection.map( (l) -> return l.get('minimum'))
         maxs = @collection.map( (l) -> return l.get('maximum'))
         globalMin = Math.min.apply(Math, mins)
         globalMax = Math.max.apply(Math, maxs)
         @wfits.setExtent(globalMin, globalMax)
+        @collection.hasExtent = true

       @wfits.setImage(band)
       @wfits.setStretch(@stretch)


Debug draw: Fix frustum culling.

Debug draw: Fix frustum culling.

--- engine/debug_draw.coffee
+++ engine/debug_draw.coffee
@@ -93,6 +93,7 @@
         else
             vec3.copy dob.scale, ob.body.half_extents
         dob._update_matrices()
+        dob.radius = ob.radius

         # occluded pass
         color4.set color, 1, 1, 1, @hidden_alpha