update toolbar on hotkeys

update toolbar on hotkeys

--- src/modules/keyboard.coffee
+++ src/modules/keyboard.coffee
@@ -26,14 +26,19 @@
     @hotkeys[which].push(hotkey)

   toggleFormat: (range, format) ->
-    delta = @quill.getContents(range)
-    value = !_.all(delta.ops, (op) ->
+    if range.isCollapsed()
+      delta = @quill.getContents(Math.max(0, range.start-1), range.end)
+    else
+      delta = @quill.getContents(range)
+    value = delta.ops.length == 0 or !_.all(delta.ops, (op) ->
       return op.attributes[format]
     )
     if range.isCollapsed()
       @quill.prepareFormat(format, value)
     else
       @quill.formatText(range, format, value, 'user')
+    toolbar = @quill.getModule('toolbar')
+    toolbar.setActive(format, value) if toolbar?

   _initDeletes: ->
     _.each([DOM.KEYS.DELETE, DOM.KEYS.BACKSPACE], (key) =>


EditorPane: Existence check for kite and method.

--- client/ide/lib/workspace/panes/ideeditorpane.coffee
+++ client/ide/lib/workspace/panes/ideeditorpane.coffee
@@ -49,7 +49,7 @@
   getFileModifiedDate: (callback = noop) ->

     path = FSHelper.plainPath @file.path
-    @file.machine.getBaseKite().fsGetInfo({ path }).then (info) ->
+    @file.machine.getBaseKite()?.fsGetInfo?({ path }).then (info) ->
       callback info.time


IDE.ShortcutsView: (dry) use KD.utils.isNavigatorApple

--- client/ide/views/shortcutsview/shortcutsview.coffee
+++ client/ide/views/shortcutsview/shortcutsview.coffee
@@ -7,8 +7,7 @@
     @wrapper.setClass 'key-mappings'

     shortcuts = @getShortcuts()
-    apples    = [ "MacIntel", "MacPPC", "Mac68K", "Macintosh", "iPad" ]
-    isApple   = apples.indexOf(navigator.platform) > -1
+    isNavigatorApple = KD.utils.isNavigatorApple()

     for title, mapping of shortcuts
       container = new KDCustomHTMLView
@@ -19,7 +18,7 @@
         metaKey   = 'Ctrl'
         key       = 'Others'

-        if isApple
+        if isNavigatorApple
           metaKey = 'Cmd'
           key     = 'Apple'


Add `review` button to flow

Add `review` button to flow

--- src/adapters/slack.coffee
+++ src/adapters/slack.coffee
@@ -180,7 +180,7 @@
               msg.attachments.push
                 text: "<@#{user.id}|#{user.name}> is now assigned to this ticket"
             resolve()
-        when "devready", "inprogress", "done"
+        when "devready", "inprogress", "review", "done"
           result = Utils.fuzzyFind action.value, Config.maps.transitions, ['jira']
           if result
             msg.attachments.push @buttonAttachmentsForState action.name,
@@ -255,6 +255,12 @@
       type: "button"
       value: "top"

+    review =
+      name: "review"
+      text: "Review"
+      type: "button"
+      value: "review"
+
     done =
       name: "done"
       text: "Done"
@@ -264,6 +270,8 @@

     switch state
       when "inprogress"
+        actions = [ review, done ]
+      when "review"
         actions = [ done ]
       when "done"
         actions = [ devready, inprogress ]


Add isFunc and isObject convenience methods.

--- src/stochator.coffee
+++ src/stochator.coffee
@@ -1,5 +1,9 @@
 isType = (type) ->
     (arg) -> Object::toString.call(arg) == "[object #{ type }]"
+
+isFunc = isType("Function")
+
+isObject = isType("Object")

 callFunctions = (fns) -> (fn() for fn in fns)


change initial condition after pattern change

--- atmospheric/001-balanced-temperature/avgtfield.coffee
+++ atmospheric/001-balanced-temperature/avgtfield.coffee
@@ -46,8 +46,8 @@
     lat = (j) -> Math.PI / 256 * (128 - j)

     #avgt.init = (263.15 for i in [0...256])
-    avgt.init = (243.15 + 20 * Math.cos(lat(i)) for i in [0...256])
-    #avgt.init = (303.15 for i in [0...256])
+    #avgt.init = (243.15 + 20 * Math.cos(lat(i)) for i in [0...256])
+    avgt.init = (303.15 for i in [0...256])

     avgt.evolve =  (data, energyIn) ->
         [gland, land, gair, air] = data


redirects

redirects

--- js/outer.coffee
+++ js/outer.coffee
@@ -55,6 +55,75 @@

   # Doc
   class Docs extends Page
+    rewrite_old_name: (name) =>
+      console.log name
+      switch name
+        when "/configuration" then "/reference/configuration"
+        when "/configuration#overview" then "/reference/configuration#overview"
+        when "/configuration#phases" then "/reference/configuration#phases"
+        when "/configuration#machine" then "/reference/configuration#machine"
+        when "/configuration#checkout" then "/reference/configuration#checkout"
+        when "/configuration#dependencies" then "/reference/configuration#dependencies"
+        when "/configuration#database" then "/reference/configuration#database"
+        when "/configuration#test" then "/reference/configuration#test"
+        when "/configuration#notify" then "/reference/configuration#notify"
+        when "/configuration#deployment" then "/reference/configuration#deployment"
+
+        when "/config-sample" then "/config_sample"
+        when "/config-sample#overview" then "/config_sample#overview"
+        when "/config-sample#sample" then "/config_sample#sample"
+
+        when "/common-problems" then "/troubleshooting/common_problems"
+        when "/common-problems#intro" then "/troubleshooting/common_problems"
+        when "/common-problems#file-ordering" then "/file_ordering"
+        when "/common-problems#missing-log-dir" then "/missing_log_dir"
+        when "/common-problems#missing-file" then "/missing_file"
+        when "/common-problems#time-day" then "/time_day"
+        when "/common-problems#time-seconds" then "/time_seconds"
+        when "/common-problems#requires-admin" then "/requires_admin"
+        when "/common-problems#oom" then "/oom"
+        when "/common-problems#wrong-ruby-version" then "/wrong_ruby_version"
+        when "/common-problems#dont-run" then "/dont_run"
+        when "/common-problems#git-bundle-install" then "/git_bundle_install"
+        when "/common-problems#git-pip-install" then "/git_pip_install"
+        when "/common-problems#wrong-commands" then "/wrong_commands"
+        when "/common-problems#bundler-latest" then "/bundler_latest"
+        when "/common-problems#capybara-timeout" then "/capybara_timeout"
+        when "/common-problems#clojure-12" then "/clojure_12"
+
+        when "/environment" then "/reference/environment"
+        when "/environment#linux" then "/reference/environment#linux"
+        when "/environment#env-vars" then "/reference/environment#env-vars"
+        when "/environment#browsers" then "/reference/environment#browsers"
+        when "/environment#languages" then "/reference/environment#languages"
+        when "/environment#databases" then "/reference/environment#databases"
+
+        when "/faq" then "/troubleshooting/common_problems"
+        when "/faq#permissions" then "/permissions"
+        when "/faq#what-happens" then "/what_happens"
+        when "/faq#look-at-code" then "/look_at_code"
+        when "/faq#parallelism" then "/parallelism"
+        when "/faq#versions" then "/reference/environment"
+        when "/faq#external-resources" then "/external_resources"
+        when "/faq#cant-follow" then "/cant_follow"
+
+        when "/manually" then "/getting_started/manually"
+        when "/manually#standard" then "/getting_started/manually#standard"
+        when "/manually#overview" then "/getting_started/manually#overview"
+        when "/manually#circle-yml" then "/getting_started/manually#circle-yml"
+        when "/manually#machine" then "/getting_started/manually#machine"
+        when "/manually#checkout" then "/getting_started/manually#checkout"
+        when "/manually#dependencies" then "/getting_started/manually#dependencies"
+        when "/manually#databases" then "/getting_started/manually#databases"
+        when "/manually#tests" then "/getting_started/manually#tests"
+        when "/manually#next" then "/getting_started/manually#next"
+
+        when "/getting-started" then "/getting_started/general"
+        when "/getting-started#overview" then "/getting_started/general#overview"
+        when "/getting-started#what-next" then "/getting_started/general#what-next"
+
+        else false
+
     filename: (cx) =>
       name = cx.params.splat[0]
       if name
@@ -120,6 +189,9 @@
       articles

     render: (cx) =>
+      rewrite = @rewrite_old_name cx.params.splat[0]
+      if rewrite
+        return cx.redirect "/docs" + rewrite
       name = @filename cx
       $("body").attr("id","docs-page").html(HAML['header'](renderContext))
       $("body").append(HAML['title'](renderContext))


C, Y, D(linewise-bound operator) should be mapped visual-mode globally

This is important so that user can still differentiate Y and y in
visual.linewise

--- keymaps/vim-mode-plus.cson
+++ keymaps/vim-mode-plus.cson
@@ -641,6 +641,9 @@
   'V': 'vim-mode-plus:activate-linewise-visual-mode'
   'ctrl-v': 'vim-mode-plus:activate-blockwise-visual-mode'
   'enter': 'vim-mode-plus:create-persistent-selection'
+  'D': 'vim-mode-plus:delete-line'
+  'C': 'vim-mode-plus:change-line'
+  'Y': 'vim-mode-plus:yank-line'

 'atom-text-editor.vim-mode-plus.has-persistent-selection.normal-mode, atom-text-editor.vim-mode-plus.visual-mode':
   'I': 'vim-mode-plus:insert-at-start-of-target'
@@ -648,18 +651,13 @@
   # 'p': 'vim-mode-plus:swap-with-register'
   # 'P': 'vim-mode-plus:swap-with-register'

-# visual-characterwise
-# -------------------------
-'atom-text-editor.vim-mode-plus.visual-mode.characterwise':
-  'D': 'vim-mode-plus:delete-line'
-  'C': 'vim-mode-plus:change-line'
-  'Y': 'vim-mode-plus:yank-line'
-
 # visual-blockwise
 # -------------------------
 'atom-text-editor.vim-mode-plus.visual-mode.blockwise':
   'o': 'vim-mode-plus:blockwise-other-end'
   'O': 'vim-mode-plus:reverse-selections'
+  'D': 'vim-mode-plus:delete-to-last-character-of-line'
+  'C': 'vim-mode-plus:change-to-last-character-of-line'

 # Input mini editor e.g. mark, surround, find, till.
 # -------------------------


:lipstick:

:lipstick:

--- src/atom/root-view.coffee
+++ src/atom/root-view.coffee
@@ -43,5 +43,5 @@
           @fileFinder = FileFinder.build
             urls: relativePaths
             selected: (relativePath) => @editor.setBuffer(@project.open(relativePath))
-          @addPane(@fileFinder)
+          @addPane @fileFinder
           @fileFinder.input.focus()


Test route create methods

Test route create methods

--- src/test/core.coffee
+++ src/test/core.coffee
@@ -1,6 +1,44 @@
 (->
-	describe 'Trocha Js Routes List engine', ->
-		describe 'Constants', ->
+	describe 'Trocha JS Routes List engine', ->
+		describe 'Route creation', ->
+			it 'should create routes via JSON Constructor', ->
+				r = trocha {
+					routes:
+						simple_route :{}
+						simple_scope: {$type: trocha.SCOPE}
+						simple_alias: "simple_alias"
+						simple_resource:
+							$type: trocha.RESOURCE
+							$id: "simple_id" #resource must have ID
+				}
+				assert r.simple_route, {}
+				assert r.simple_scope, {}
+				assert r.simple_resource, {}
+				#assert r.simple_alias, {} #will fail
+				assert r.simple_alias, "simple_alias" # @TODO remove me after alias fix
+			it 'should create routes via post init functions', ->
+				r = trocha()
+				r._newRoute {
+					name: "simple_route"
+				}
+				r._newScope {
+					name: "simple_scope"
+				}
+				r._newResource {
+					name: "simple_resource"
+					id: "simple_id"
+				}
+				r._newAlias {
+					name: "simple_alias"
+					alias: "simple_alias"
+				}
+				assert r.simple_route, {}
+				assert r.simple_scope, {}
+				assert r.simple_resource, {}
+				assert r.simple_alias, "simple_alias"
+				console.log r
+
+		describe 'Constants returns', ->
 			it 'should return HTTP request methods types', ->
 				assert trocha.OPTIONS, "OPTIONS"
 				assert trocha.GET, "GET"


feat(model generator): add a model schema as a standard place to list and document your model's ttributes

--- generators/model/templates/model.coffee
+++ generators/model/templates/model.coffee
@@ -20,6 +20,7 @@

     'use strict'

+
     ###*<% if ( description ) { %>
     #   <%- description %>
     #<% } %>
@@ -29,7 +30,30 @@
     #   @constructor<% } %>
     ###

-    class <%- className %> extends Backbone.Model<% if ( singleton ) { %>
+    class <%- className %> extends Backbone.Model
+
+        ###*
+        #   List of [valid attribute names](#attrs).
+        #
+        #   @property       schema
+        #
+        #   @type           Array[String]
+        #   @static
+        #   @final
+        ###
+
+        ###*
+        #   The `<%- className %>`'s unique identifier.
+        #
+        #   @attribute      id
+        #
+        #   @type           String
+        ###
+
+        schema: [
+
+            'id'
+        ]<% if ( singleton ) { %>

     ##  Export singleton.


add toggleClassRadio jquery fn

add toggleClassRadio jquery fn

--- app/assets/javascripts/ab_admin/core/utils.js.coffee
+++ app/assets/javascripts/ab_admin/core/utils.js.coffee
@@ -105,6 +105,10 @@
   else
     $el.click()

+$.fn.toggleClassRadio = (class_name = 'active', state = undefined) ->
+  @each ->
+    $(this).toggleClass(class_name, state).siblings().removeClass(class_name)
+
 $.parseQuery = ->
   window.location.search.replace("?", "").parseQuery()


fixing error in meta data

fixing error in meta data

Former-commit-id: dfdc4ad3308ae976981369589069e5abc49af2b6 [formerly 04cbccb61c04d8a5a27e6db3cb04b373e1d6d812] [formerly 5070576b2f25cd14ee64ce346f8dc4e8726f7b86 [formerly 5070576b2f25cd14ee64ce346f8dc4e8726f7b86 [formerly 52d23d4904e5ec9ddd3953c21b807aa6537340d7]]]
Former-commit-id: 07f5e67021cc11dd3750becb943bdd103fef8729 [formerly 5a949f2ae89df8c18beed50d786e42faa42141a5]
Former-commit-id: c2b260fa24dc314437c9ecace4aa56dc9560450d
Former-commit-id: 23c56d7248a9962fa091b71c7c4a48ac00b7fcc8

--- app/assets/javascripts/backbone/entities/meta.coffee
+++ app/assets/javascripts/backbone/entities/meta.coffee
@@ -26,7 +26,7 @@
       @active_meta

     changeToDefault : ->
-      @active_meta.setMeta {}, true
+      @setMeta {}, true

   App.reqres.setHandler 'meta:get', ->
     API.getMeta()


Remove reason from encounter,performed datatype (#57)

--- app/assets/javascripts/datatypes/encounter.js.coffee
+++ app/assets/javascripts/datatypes/encounter.js.coffee
@@ -124,7 +124,6 @@
     @_locationPeriodHigh = CQL_QDM.Helpers.convertDateTime(@entry.facility?['end_time'])
     @_facilityLocation = @entry.facility?.code
     @_negationRationale = @entry.negationReason
-    @_reason = @entry.reason
     @_relevantPeriodLow = CQL_QDM.Helpers.convertDateTime(@entry.start_time)
     if @entry.end_time
       @_relevantPeriodHigh = CQL_QDM.Helpers.convertDateTime(@entry.end_time)
@@ -185,12 +184,6 @@
     new cql.Code(@_negationRationale?.code, @_negationRationale?.code_system)

   ###
-  @returns {Code}
-  ###
-  reason: ->
-    new cql.Code(@_reason?.code, @_reason?.code_system)
-
-  ###
   @returns {Interval<Date>}
   ###
   relevantPeriod: ->


OX-187 performance testing on server

OX-187 performance testing on server

--- app/assets/javascripts/model/binary/pullqueue.coffee
+++ app/assets/javascripts/model/binary/pullqueue.coffee
@@ -169,7 +169,6 @@
         sum += t

       avg = sum / @roundTripTimes.length
-      console.log sum, @roundTripTimes.length
       console.log "ping - min:", _.min(@roundTripTimes), "max:", _.max(@roundTripTimes), "avg:", avg

     #if @roundTripTime? and @bucketTime?
@@ -187,8 +186,8 @@

     new ArrayBufferSocket(
       senders : [
-        new ArrayBufferSocket.WebSocket("ws://#{document.location.host}/binary/ws?dataSetId=#{@dataSetId}&cubeSize=#{1 << @cube.BUCKET_SIZE_P}")
-        #new ArrayBufferSocket.XmlHttpRequest("/binary/ajax?dataSetId=#{@dataSetId}&cubeSize=#{1 << @cube.BUCKET_SIZE_P}")
+        #new ArrayBufferSocket.WebSocket("ws://#{document.location.host}/binary/ws?dataSetId=#{@dataSetId}&cubeSize=#{1 << @cube.BUCKET_SIZE_P}")
+        new ArrayBufferSocket.XmlHttpRequest("/binary/ajax?dataSetId=#{@dataSetId}&cubeSize=#{1 << @cube.BUCKET_SIZE_P}")
       ]
       requestBufferType : Float32Array
       responseBufferType : Uint8Array


Fixed #398 missing Diaglo#setContent method

--- wzk/ui/dialog/Dialog.coffee
+++ wzk/ui/dialog/Dialog.coffee
@@ -1,11 +1,13 @@
 goog.provide 'wzk.ui.dialog.Dialog'

-goog.require 'wzk.ui.dialog.ButtonSet'
+goog.require 'goog.dom.classes'
+goog.require 'goog.dom.safe'
+goog.require 'goog.html.SafeHtml'
 goog.require 'goog.string'
 goog.require 'goog.ui.Dialog.DefaultButtonKeys'
+
+goog.require 'wzk.ui.dialog.ButtonSet'
 goog.require 'wzk.ui.CloseIcon'
-goog.require 'goog.dom.classes'
-goog.require 'goog.dom.safe'

 class wzk.ui.dialog.Dialog extends goog.ui.Dialog

@@ -30,6 +32,16 @@
       btnSet.set goog.ui.Dialog.DefaultButtonKeys.YES, captYes
     if captNo?
       btnSet.set goog.ui.Dialog.DefaultButtonKeys.NO, captNo
+
+  ###*
+    Allows to set a HTML fron unsave string.
+    @suppress {accessControls}
+    @param {string} html
+  ###
+  setContent: (html) ->
+    @content_ = goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(html, null)
+    if @contentEl_?
+      goog.dom.safe.setInnerHtml(@contentEl_, @content_)

   open: ->
     @setVisible true
@@ -122,7 +134,7 @@
     @element_ = @dom_.el 'div', 'modal fade in'
     main = @dom_.el 'div', 'modal-dialog', @element_
     @buildContentWrapper main
-
+
     @manageBgMask()

     @buildHeader()


Update byte constants test

Update byte constants test

--- spec/powershell-spec.coffee
+++ spec/powershell-spec.coffee
@@ -304,8 +304,8 @@
       it "tokenizes constant value in bytes", ->
         for constant in constants
           {tokens} = grammar.tokenizeLine constant
-          expect(tokens[0].value).toEqual constant
-          expect(tokens[0]).toHaveScopes ["constant.numeric.integer.bytes.powershell"]
+          for token in tokens
+            expect(token).toHaveScopes ["source.powershell", "constant.numeric.scientific.powershell"]

     describe "Constant float values", ->
       constants = [


Fix imported component name

Fix imported component name

--- src/embed.coffee
+++ src/embed.coffee
@@ -14,7 +14,7 @@
     models       = require 'cs!app/models'
     p13n         = require 'cs!app/p13n'
     ColorMatcher = require 'cs!app/color'
-    BaseMapView  = require 'cs!app/map-base-view'
+    MapBaseView  = require 'cs!app/map-base-view'
     map          = require 'cs!app/map'
     TitleView    = require 'cs!app/views/embedded-title'

@@ -28,7 +28,7 @@
         currentUri.segment(0, "").toString()

     ICON_SIZE = 40
-    class EmbeddedMapView extends BaseMapView
+    class EmbeddedMapView extends MapBaseView
         getIconSize: ->
             if $(window).innerWidth() < 150 or $(window).innerHeight < 150
                 return ICON_SIZE * 0.5


Limit ship rotation on movement

Limit ship rotation on movement

--- app/scripts/components/player/PlayerSpaceship.coffee
+++ app/scripts/components/player/PlayerSpaceship.coffee
@@ -119,7 +119,7 @@
       @updateAcceleration()

       r = @rotation
-      newR = shipSpeedY / 20
+      newR = shipSpeedY / 40
       nr = r
       if r < newR
         nr += 1


Reset fixtures before testing SSH modals

--- test/integration/ssh_platform_detect.coffee
+++ test/integration/ssh_platform_detect.coffee
@@ -1,6 +1,7 @@
 require './setup_teardown'
 should = require 'should'
 {wd40, browser, loginAndGo} = require './helper'
+cleaner = require '../cleaner'

 clickSSHButton = (done) ->
   wd40.click '#toolbar a[href$="/settings"] .dropdown-toggle', (err) ->
@@ -10,6 +11,10 @@
 # TODO(pwaller): Conditionally disable modal depending on whether we're in
 # an environment that supports it.
 (if process.env.SKIP_MODAL then xdescribe else describe) 'Platform-specific SSH instructions', ->
+
+  before (done) ->
+    # Needed so that SSH keys are deleted
+    cleaner.clear_and_set_fixtures done

   before (done) ->
     loginAndGo "ehg", "testing", "/dataset/3006375731", done
@@ -88,3 +93,4 @@

     it 'the modal window shows me the commands I should run', =>
       @modalTextContent.should.include 'xclip -sel clip < ~/.ssh/id_rsa.pub'
+


Fixed : Tree not clearing when 'New Scenario' done multiple times

--- src/main/webapp/lib/views/AppView.coffee
+++ src/main/webapp/lib/views/AppView.coffee
@@ -111,6 +111,7 @@

   newScenario: ->
     $a.broker.trigger('map:clear_map')
+    $a.broker.trigger('app:tree_clear')
     $a.map.setZoom(AppView.INITIAL_ZOOM_LEVEL)
     $a.models = new $a.Scenario()
     $a.models.networkset().set('network',[new $a.Network()])


Fix removal of createColorGroupTintButtons in Thang editor

--- app/views/editor/thang/ThangTypeColorsTabView.coffee
+++ app/views/editor/thang/ThangTypeColorsTabView.coffee
@@ -36,7 +36,6 @@
     super()
     return unless @supermodel.finished()
     @createShapeButtons()
-    @createColorGroupTintButtons()
     @initStage()
     @initSliders()
     @tryToBuild()


[Completes #28028811] upon / any link

[Completes #28028811] upon / any link

--- web/astrolin.coffee
+++ web/astrolin.coffee
@@ -20,6 +20,8 @@
       tracker: "203533"
     lin:
       tracker: "265847"
+    upon:
+      tracker: "265847"
     precious:
       tracker: "203533"
     sin:
@@ -34,7 +36,7 @@
   # Project links
   linkage: (project, details) ->
     if details is undefined
-      return { "project's unknown": "/" }
+      return { "none such showing yet": "http://github.com/astrolet" }

     github = "https://github.com/astrolet/"
     ghpages = "http://astrolet.github.com/"


movable velocity and acceleration getters

--- test/movable.coffee
+++ test/movable.coffee
@@ -35,7 +35,7 @@
 test "should increase velocity according to acceleration", ->
   particle = GameObject
     velocity: Point(7, 4)
-    acceleration: Point(1, -0.3)
+    acceleration: Point(0, -0.3)

   60.times ->
     particle.update(1/60)


Removed duplicate access points from ssid list

--- src/wifi-scan.coffee
+++ src/wifi-scan.coffee
@@ -1,5 +1,6 @@
 Promise = require 'bluebird'
 child_process = Promise.promisifyAll require 'child_process'
+_ = require 'lodash'

 config = require './config'

@@ -32,8 +33,10 @@
 		for own bss, details of bsss
 			networks.push(details)

-		# sort by signal strength
-		return networks.sort((a, b) -> b.signal - a.signal)
+		# sort by signal strength and remove duplicates
+		networks = _(networks).orderBy('signal', 'desc').uniqBy('ssid').value()
+
+		return networks
 	.catch code: 240, (e) ->
 		Promise.delay(1000) # Delay needed to avoid `Command failed: iw wlan0 scan ap-force command failed: Device or resource busy (-16)`
 		.then(exports.scanAsync)


.

Former-commit-id: 558fa0ba6af77619146e87810615058ae62658ac [formerly 2444817f6edc82ab33923b234e417e488a077413] [formerly 143fb2337d4c2fcabff628a8b7d0f0b84228efa2 [formerly 59e00704872692054d6b192e211588171403818e]] [formerly c8adcf65b5ee0a57cdf9d99c5fe0437fec849a66 [formerly 691e18cf0989f7959cad74ea9204c4fbe774bcc1] [formerly cb28dcf9fb82d10a014332338a7f460eec2821b6 [formerly cb28dcf9fb82d10a014332338a7f460eec2821b6 [formerly 1040747de51dd0651d286edeffaab83bffd061ea]]]]
Former-commit-id: 049711058d653486d565b00e6db7495a0dba354b [formerly c59ce54469e1fd9323666638b0bd21b96e82dac4] [formerly d59b3349cb500ce44a5183d419fac7adaf6a48f2 [formerly 44ff77736c09849a668ae07a170163deea8b999c]]
Former-commit-id: 048ca38f45073125e916d7feea78f22aabdcbab8 [formerly 7209cf9acfbf1ea20c1498f2dff24742d9bd6432]
Former-commit-id: 7099380aa2b1bacc8dd3c72bc550cce3b072d8ac
Former-commit-id: 21b4399dd6d70b20408f5e4a4dd6ecf025a3d4f3

--- @client/customizations.coffee
+++ @client/customizations.coffee
@@ -1693,7 +1693,7 @@

 customizations.bitcoin =
   show_proposer_icon: true
-  collapse_descriptions_at: 600
+  collapse_descriptions_at: 300
   slider_pole_labels: support_oppose

 customizations.bitcoinfoundation = customizations['bitcoinfoundationarchive'] =
@@ -1711,8 +1711,6 @@

   # default proposal options
   show_proposer_icon: true
-  collapse_descriptions_at: 600
-
   homie_histo_title: "Votes"
   collapse_descriptions_at: 300


.

Former-commit-id: b49a135c71e7bd7314c9318c20e56217032aa945 [formerly 1733b9a4cd6e6d6b2f07307b4745703216a22584] [formerly 9555c6f68578e4f1a72ad91d94cc89050ad34ce9 [formerly 73da49ae6b91be353721c6ecda8f8124f452eb54]] [formerly b87bb0d7f1d1c1f14f22d9dcfc5f3336268b88a8 [formerly 28daf3d13f7983e5b7b42124ea9cfca208d15f15] [formerly 815886f2b87f1eeb7347a822a84585deb3be13e7 [formerly 815886f2b87f1eeb7347a822a84585deb3be13e7 [formerly e8e485eaf12e9aeb447b148e3eeeecd88576d119]]]]
Former-commit-id: 3623150e6f71eb930653fd473b1caf67d0e4c921 [formerly 411f1e942bf136e0b0511859f894c29fb60e6e1e] [formerly fc97ccad7073321cbd13385128dc751725de94cb [formerly 90e04adbc85edeb5f10355dbba52c3f99c3f2605]]
Former-commit-id: a19b5df4389fbe4d866c26f09055dd12e9f94298 [formerly 5b9934360737f4c8dc02464305c08e597d690897]
Former-commit-id: 4698810b425942df30a1bad209fa021342e98a91
Former-commit-id: 99b91665b8388a1f774e025232ccc2472fa64ab7

--- @client/customizations.coffee
+++ @client/customizations.coffee
@@ -460,7 +460,7 @@
           style:
             position: 'absolute'
             width: 1300
-          src: asset('ecast/bg.png')
+          src: asset('ecast/bg-small.png')

         # Title of site
         DIV
@@ -513,7 +513,7 @@
                 display: 'block'
                 marginTop: 4
                 width: 215
-              src: asset('ecast/ecast.png')
+              src: asset('ecast/ecast-small.png')

           # DIV
           #   style:


names

names

--- resources/assets/coffee/react/beatmapset-page/description-editor.coffee
+++ resources/assets/coffee/react/beatmapset-page/description-editor.coffee
@@ -34,6 +34,7 @@
   componentWillUnmount: =>
     # stuff

+
   onInput: (_e) =>
     @setState rawValue: @refs.body.value

@@ -55,9 +56,9 @@

   render: =>
-    el 'form', null,
+    el 'form', className: 'post-editor',
       el 'textarea',
-        className: 'post-editor'
+        className: 'post-editor__textarea'
         name: 'body'
         value: @state.rawValue
         onChange: @onInput # binds to oninput, not onchange
@@ -148,7 +149,6 @@
               span className: 'btn-circle__content',
                 i className: 'fa fa-image'

-
             label
               className: 'bbcode-size-select'
               title: osu.trans('bbcode.size._'),


fix(signatures): temporarily disable signatures in preferences

--- internal_packages/composer-signature/lib/main.coffee
+++ internal_packages/composer-signature/lib/main.coffee
@@ -16,7 +16,8 @@
       displayName: "Signatures"
       component: require "./preferences-signatures"

-    PreferencesSectionStore.registerPreferenceSection(@sectionConfig)
+    # TODO Re-enable when fixed!
+    # PreferencesSectionStore.registerPreferenceSection(@sectionConfig)

     ## TODO:
     # PreferencesSectionStore.registerPreferences "composer-signatures", [


don't delete HITs

don't delete HITs

Comment by @mizzao on PR #13:
> MTurk deletes HITs after a while (they aren't returned by `GetHIT`),
> but I'm not sure we'd want to remove them from the local database.

--- admin/admin.coffee
+++ admin/admin.coffee
@@ -238,8 +238,6 @@
       # (see mturk/test/test.js)
       if hitData.HITId
         HITs.update {HITId: HITId}, $set: hitData
-      else
-        HITs.remove {HITId: HITId}
     catch e
       throw new Meteor.Error(500, e.toString())


Amend notification message

Amend notification message

--- admin/admin.coffee
+++ admin/admin.coffee
@@ -236,9 +236,8 @@
       catch e
         throw new Meteor.Error(500, e.toString())

-      Meteor._debug(chunk.length + " workers notified")
-
       count += chunk.length
+      Meteor._debug(count + " workers notified")

     return count


modified

modified

--- dev/observer.coffee
+++ dev/observer.coffee
@@ -49,7 +49,7 @@
           系統內部用的是前半部分,英文部分是針對Python接口的
         ###
         券商接口.提取資料 '查詢持倉,getPosition'
-        券商接口.提取資料 '查可撤單,getWOrders'
+        #券商接口.提取資料 '查可撤單,getWOrders'

       interval = setInterval 跟蹤行情, 間隔


whitespace

whitespace

--- vendor/assets/javascripts/nifty/dialog.coffee
+++ vendor/assets/javascripts/nifty/dialog.coffee
@@ -1,15 +1,15 @@
 window.Nifty ||= {}
 window.Nifty.Dialog =
-
+
   # The numerical ID to start showing dialogs from
   startingID: 1
-
+
   # A callback reference which is run on content set if set.
   onSetContent: null
-
+
   # Stores all behaviors
   behaviors: {}
-
+
   # Open a new dialog which will accept a number of possible options.
   #
   #   id         => the ID to assign to this dialog (prefixed with 'niftyDialog-' )
@@ -39,30 +39,30 @@
     # set a dialog ID for this dialog
     dialogsOpen = $('div.niftyDialog').length
     dialogID = if dialogsOpen == 0 then this.startingID else (dialogsOpen * 10) + this.startingID
-
+
     options.id = dialogID unless options.id?

     # create a template and assign the ID
     dialogTemplate = $("

")
     dialogTemplate.data('dialogID', dialogID)
-
+
     # insert the dialog into the page
     insertedDialog = dialogTemplate.appendTo($('body'))
     insertedDialog.css('z-index', 2000 + dialogID)
-
+
     # set the content on the dialog
     insertedDialog.data('options', options)
-
+
     overlayClass = ''
     overlayClass = 'invisible' if dialogID > 1
     theOverlay = $("

").insertBefore(insertedDialog).css('z-index', 2000 + dialogID - 1)
     theOverlay.fadeIn('fast')
-
+
     # if we have a width, set the width for the dialog
     if options.width?
       insertedDialog.css('width', "#{options.width}px")
       insertedDialog.css('margin-left', "-#{options.width / 2}px")
-
+
     if options.offset?
       insertedDialog.css('margin-top', "#{options.offset}px")

@@ -72,9 +72,9 @@
       insertedDialog.css
         'margin-left': "#{x}px"
         'margin-top': "#{y}px"
-

-    # Set the closing action for the inserted dialog to close dialog
+
+    # Set the closing action for the inserted dialog to close dialog
     # and fade out the appropriate overlay
     insertedDialog.data 'closeAction', =>
       options.onClose.call(null, insertedDialog, options) if options.onClose?
@@ -85,7 +85,7 @@

     # Set that clicking on the dialog's overlay will close the dialog
     theOverlay.on 'click', -> insertedDialog.data('closeAction').call()
-
+
     # load in the content
     if options.url?
       # if loading from a URL, do this
@@ -93,14 +93,14 @@
       insertedDialog.addClass 'loading'
       if options.behavior? && behavior = this.behaviors[options.behavior]
         behavior.beforeLoad.call(null, insertedDialog, options) if behavior.beforeLoad?
-
+
       $.ajax
         url: options.url
         success: (data)=> this.displayDialog(insertedDialog, data)
-
+
     else if options.html?
       this.displayDialog(insertedDialog, options.html)
-
+
     else
       # anything else won't work
       console.log "Dialog could not be displayed. Invalid options passed."
@@ -115,7 +115,7 @@
     else
       console.log "Must pass a 'name' option to the addBehavior method."
       false
-
+
   # Complete the opening of a dialog with the given HTML
   displayDialog: (dialog, content)->
     dialog.html(content)
@@ -149,7 +149,7 @@
       $.ajax
         url: options.url
         success: (data)=> this.setContent(data, id)
-
+
   # Create a new overlay
   createOverlay: (options)->
     overlay = $("

")
@@ -160,10 +160,10 @@
       overlay.fadeOut 'fast', ->
         overlay.remove()
     overlay.fadeIn('fast')
-
+
   # Closes the top dialgo in the dialog stack
   closeTopDialog: ->
     if $('div.niftyDialog').length
       $('div.niftyDialog:last').data('closeAction').call()
-
-  +
+


add ng-callback to ng-upload

add ng-callback to ng-upload

--- lib/assets/javascripts/directives/ngupload.js.coffee
+++ lib/assets/javascripts/directives/ngupload.js.coffee
@@ -22,7 +22,7 @@
       data.thumb = scope[unparsedModel[0]].thumb.url if scope[unparsedModel[0]].thumb
   return data

-uploadFiles = (scope,element,model,id,file,parent,timeout) ->
+uploadFiles = (scope,element,model,id,file,parent,timeout,callback) ->
   scope.progress = 0
   element.addClass('covered')
   route = Routes[element[0].attributes['ng-model'].value.split('.')[0] + '_path'](id: id) + '.json'
@@ -44,7 +44,7 @@
         scope[model[0]].thumb = data.thumb
         scope.progress = 100
         element.removeClass('covered')
-
+        scope.$eval(callback) if callback
     else if this.readyState == 4 && this.status > 399
       failed()
   , false
@@ -81,8 +81,10 @@
         fileData(scope,attributes)

     controller: ($scope, $element, $http, $timeout) ->
+      callback = ->
+        $element[0].attributes['ng-callback'].value if $element[0].attributes['ng-callback']
       $scope.uploadFiles = (model,id,file,parent) ->
-        uploadFiles($scope,$element,model,id,file,parent,$timeout)
+        uploadFiles($scope,$element,model,id,file,parent,$timeout,callback())
       $scope.progress = 0
       $scope.uploadProgress = ->
         return $scope.progress
@@ -117,6 +119,8 @@
         return attributes.accept if attributes.accept
         return '*'
     controller: ($scope, $element, $http, $timeout) ->
+      callback = ->
+        $element[0].attributes['ng-callback'].value if $element[0].attributes['ng-callback']
       $scope.show = (type) ->
         options = $element[0].attributes['ng-upload-options'].value.replace('{','').replace('}','').split(',')
         for option in options
@@ -124,4 +128,4 @@
             return true if option.indexOf('true') > -1
         return false
       $scope.uploadFiles = (model,id,file,parent) ->
-        uploadFiles($scope,$element,model,id,file,parent,$timeout)
+        uploadFiles($scope,$element,model,id,file,parent,$timeout,callback())


Sidebar: Implemented create new workspace from sidebar.

--- client/Social/Activity/sidebar/activitysidebar.coffee
+++ client/Social/Activity/sidebar/activitysidebar.coffee
@@ -450,6 +450,10 @@
     @activityLink?.unsetClass 'selected'

     if event.target.nodeName is 'SPAN'
+
+      if machineItem.type is 'title'
+        if event.target.classList.contains 'ws-add-icon'
+          return @addNewWorkspace machineItem

       if status?.state is Running
         KD.utils.stopDOMEvent event
@@ -579,6 +583,72 @@
     #       KD.getSingleton('router').handleRoute "/IDE/VM/#{newMachine.uid}"

+  addNewWorkspace: (machineItem) ->
+    return if @addWorkspaceView
+
+    {machineUId} = machineItem.getData()
+    type         = 'new-workspace'
+    delegate     = machineItem.getDelegate()
+
+    @addWorkspaceView = delegate.addItem { type, machineUId }
+
+    @addWorkspaceView.child.once 'KDObjectWillBeDestroyed', =>
+      delegate.removeItem @addWorkspaceView
+      @addWorkspaceView = null
+
+    @addWorkspaceView.child.input.setFocus()
+
+
+  createNewWorkspace: (options = {}) ->
+    {name, machineUId, rootPath} = options
+    {computeController, router } = KD.singletons
+    layout                       = {}
+
+    if not name or not machineUId
+      return warn 'Missing options for create new workspace'
+
+    unless rootPath
+      rootPath       = "/home/#{KD.nick()}/Workspaces/#{name}"
+      emptyWorkspace = yes
+
+    data    = { name, machineUId, rootPath, layout }
+    machine = m for m in computeController.machines when m.uid is machineUId
+    command = "mkdir -p '#{rootPath}' ; cd '#{rootPath}' ; touch README.md"
+
+    return warn "Machine not found."  unless machine
+
+    callback = =>
+      KD.remote.api.JWorkspace.create data, (err, workspace) =>
+        return KD.showError "Couldn't create new workspace"  if err
+        view    = @addWorkspaceView
+        options =
+          title : workspace.name
+          type  : 'workspace'
+          href  : "/IDE/#{workspace.slug}"
+          data  : workspace
+
+        if view
+          list  = view.getDelegate()
+          list.removeItem view  if view
+        else
+          for key, node of @machineTree.nodes when node.type is 'title'
+            list = node.getDelegate()
+
+        list.addItem options
+
+        KD.userWorkspaces.push workspace
+
+        router.handleRoute options.href
+
+    if emptyWorkspace
+      machine.getBaseKite().exec({ command })
+      .then  (res) => callback()
+      .catch (err) ->
+        KD.showError 'Unable to create a new workspace'
+    else
+      callback()
+
+
   updateMachineTree: (callback = noop) ->

     @fetchMachines (machines) =>


client:most active channel follow state fix

--- client/activity/lib/views/activitytopicswidget.coffee
+++ client/activity/lib/views/activitytopicswidget.coffee
@@ -6,7 +6,9 @@

 module.exports = class ActivityTopicsWidget extends KDCustomHTMLView
+
   constructor: (options = {}) ->
+
     options.cssClass    = 'popular-topics-widget activity-widget'
     super options

@@ -35,9 +37,40 @@
       limit: 5
     , @bound 'createTopicsList'

+    { notificationController } = kd.singletons
+
+    notificationController
+      .on 'AddedToChannel',     @bound 'addedToChannel'
+      .on 'RemovedFromChannel', @bound 'removedFromChannel'
+
+
   createTopicsList : (err, data) ->
+
     @listController.instantiateListItems data
     @listController.hideLazyLoader()

+  addedToChannel : (update) ->
+
+    { id } = update.channel
+
+    @updateChannelFollowButtonState id, on

+
+  removedFromChannel : (update) ->
+
+    { id } = update.channel
+
+    @updateChannelFollowButtonState id, off
+
+
+  updateChannelFollowButtonState : (id, followingState) ->
+
+    return  unless channelItem = @listController.itemsIndexed[id]
+
+    channelItem.followButton.setFollowingState followingState
+
+
+
+
+


Turn off debug message

Turn off debug message

--- server.coffee
+++ server.coffee
@@ -63,7 +63,7 @@
 		#Check if user is in range of an enemy beacon, opening the app will capture the beacon
 		beacons.iterate (beacon) ->
 			if beacon.peek('owner') isnt getTeamOfUser(userId) and !found
-				log distance(geoloc.latitude, geoloc.longitude, beacon.peek('location', 'lat'), beacon.peek('location', 'lng'))
+				#log distance(geoloc.latitude, geoloc.longitude, beacon.peek('location', 'lat'), beacon.peek('location', 'lng'))
 				if distance(geoloc.latitude, geoloc.longitude, beacon.peek('location', 'lat'), beacon.peek('location', 'lng')) < beaconRadius
 					#send notifcation
 					Event.create


server: Get rid of zero-padding for dates

--- server.coffee
+++ server.coffee
@@ -28,7 +28,7 @@
 ]

 formatDate = (year, month, date) ->
-  "#{monthNames[month-1]} #{date}, #{year}"
+  "#{monthNames[month-1]} #{parseInt date}, #{year}"

 # config.json is loaded to this variable
 config = null


deletet old todo in server.coffee

deletet old todo in server.coffee

--- server.coffee
+++ server.coffee
@@ -1,4 +0,0 @@
-server a search site
-setup a channel for start destination
-log channel setup for start destinatiom
-receive a json via /channel/foo an pass it to the user


fixes

fixes

--- server.coffee
+++ server.coffee
@@ -114,7 +114,7 @@
     baseDir: __dirname + "/repos/"
     license: license
     readme: readme
-    remote: "https://github.com/communities/#{repo.name}.git"
+    remote: "git@github.com:communities/#{repo.name}.com.git"
   ghRepoCreate repo.name, options, callback


use a fallback value if not found

use a fallback value if not found

--- client/lanes/components/select-field/SelectField.cjsx
+++ client/lanes/components/select-field/SelectField.cjsx
@@ -15,6 +15,7 @@
         multiSelect:  React.PropTypes.bool
         fetchOnSelect:React.PropTypes.bool
         withClearBtn: React.PropTypes.bool
+        fallBackValue:React.PropTypes.string

     getDefaultProps: ->
         labelField: 'label', idField: 'id'
@@ -48,6 +49,8 @@
             label = _.find( @props.choices, id: model.id)?[@props.labelField]
         if label
             {id: model.id, "#{@props.labelField}": label}
+        else if @props.fallBackValue
+            @props.fallBackValue
         else if model.id
             model.id
         else


Support multi select component

Support multi select component

--- client/lanes/components/select-field/SelectField.cjsx
+++ client/lanes/components/select-field/SelectField.cjsx
@@ -4,7 +4,7 @@
     propTypes:
         choices: React.PropTypes.arrayOf(
             React.PropTypes.shape({
-                id: React.PropTypes.number
+                id: React.PropTypes.any
                 label: React.PropTypes.string
             })
         )
@@ -14,6 +14,7 @@
         setSelection: React.PropTypes.func
         displayLimit: React.PropTypes.number
         syncOptions:  React.PropTypes.object
+        multiSelect:  React.PropTypes.bool
         fetchWhenOpen: React.PropTypes.bool
         allowFreeForm: React.PropTypes.bool
         includeBlankRow: React.PropTypes.bool
@@ -40,10 +41,11 @@
         <span>{value}</span>

     getValue: ->
-        return undefined if @state.isOpen
+        return undefined if @state.isOpen and not @props.multiSelect
         return @state.tempDisplayValue if @state.tempDisplayValue
-        model = @props.getSelection?() or @model?[@props.name]
+        model = @props.getSelection?(@model, @props) or @model?[@props.name]
         return undefined unless model
+        return model if @props.multiSelect
         label = model[@props.labelField] or @props.defaultLabel
         if !label and not _.isEmpty(@props.choices)
             label = _.findWhere( @props.choices, id: model.id)?[@props.labelField]
@@ -69,22 +71,25 @@
     setModel: (model) ->
         @setState({isOpen: false, tempDisplayValue: false, requestInProgress: false})
         if @props.setSelection
-            @props.setSelection(model, parent: @model)
+            @props.setSelection(model, model: @model)
         else
             @model.set(@props.name, model)

     onChange: (value) ->
-        if _.isObject(value)
-            model = if Lanes.u.isState(value) then value else new @query.model(value)
-            model.fetch(@props.syncOptions).then(@setModel)
-            @setState(isOpen: false, tempDisplayValue: value, requestInProgress: true)
+        if @props.multiSelect
+            @setModel(value)
         else
-            if not @props.choices
-                c = @getClause()
-                return if c.value is value
-                c.value = value
-                @query.results.reload()
-            @setState(isOpen: true)
+            if _.isObject(value)
+                model = if Lanes.u.isState(value) then value else new @query.model(value)
+                model.fetch(@props.syncOptions).then(@setModel)
+                @setState(isOpen: false, tempDisplayValue: value, requestInProgress: true)
+            else
+                if not @props.choices
+                    c = @getClause()
+                    return if c.value is value
+                    c.value = value
+                    @query.results.reload()
+                @setState(isOpen: true)

     getMessages: ->
         loading = @query.results.requestInProgress
@@ -96,7 +101,8 @@

     renderEdit: (label) ->
         props = _.omit(@props, 'label')
-        select = <Lanes.Vendor.ReactWidgets.Combobox
+        Component = Lanes.Vendor.ReactWidgets[if @props.multiSelect then 'Multiselect' else 'Combobox']
+        select = <Component
             ref="select"
             className={@props.className}
             open={@state.isOpen}


Gotta make sure we change that text back for new subs.

--- avalonstar/assets/javascripts/notifier.coffee
+++ avalonstar/assets/javascripts/notifier.coffee
@@ -41,7 +41,10 @@
     # resubscriber. We use the same rail to greet them, but the text is
     # changed slightly to welcome them back.
     ($ '.js-subscribing .js-type').text(payload.title)
-    ($ '.js-subscribing .js-message').text('Welcome back to the Crusaders!') if resub
+    if resub
+      ($ '.js-subscribing .js-message').text('Welcome back to the Crusaders!')
+    else
+      ($ '.js-subscribing .js-message').text('Welcome to the Crusaders!')

     setUp(payload)
     setTimeout (->


Listing Sprint.ly items assigned to user who asks

--- src/scripts/sprintly.coffee
+++ src/scripts/sprintly.coffee
@@ -1,14 +1,19 @@
 # List stories and other items in Sprint.ly and interact with them.
 #
 # sprintly [product_id] [status] [limit] - list items in status (default status is in-progress, other values: backlog, completed, accepted; default limit is 20)
+# sprintly [product_id] mine - list items assigned to me
 # sprintly token <email:apitoken> - set/update credentials for user (required for other commands to work)
 # sprintly default 1234 - set default product_id
 #

 module.exports = (robot) ->

+  sprintlyUser = (msg) ->
+    robot.brain.data.sprintly ?= {}
+    robot.brain.data.sprintly[msg.message.user.id] ?= {}
+
   sprintly = (msg, auth) ->
-    if auth ?= robot.brain.data.sprintly?[msg.message.user.id]
+    if auth ?= sprintlyUser(msg).auth
       client = msg.http('https://sprint.ly')
         .header('accept', 'application/json')
         .header('authorization', "Basic #{new Buffer(auth).toString('base64')}")
@@ -29,8 +34,7 @@
       .scope('products.json')
       .get() (err, res, body) ->
         if res.statusCode < 400
-          robot.brain.data.sprintly ?= {}
-          robot.brain.data.sprintly[msg.message.user.id] = msg.match[1]
+          sprintlyUser(msg).auth = msg.match[1]
           msg.send "API token set"
         else
           msg.send "Unable to verify API token: #{body}"
@@ -47,6 +51,26 @@
       .scope('items.json')
       .query(query)
       .get()(formatItems(msg))
+
+  robot.respond /sprintly +(?:(\d+) +)?mine *$/, (msg) ->
+    client = sprintly(msg).product()
+    user = sprintlyUser(msg)
+
+    listMine = -> client.scope('items.json').query(assigned_to: user.user_id).get()(formatItems(msg))
+
+    if user.user_id
+      listMine()
+    else
+      client.scope('people.json').get() (err, res, body) ->
+        if res.statusCode == 200
+          payload = JSON.parse(body)
+          user_email = user.auth.split(':')[0]
+          for {id, email} in payload when email == user_email
+            user.user_id = id
+            listMine()
+            break
+        else
+          msg.send "Something came up: #{body}"

 DummyClient = ->
 self = -> this


fix incorrect displayName on `StyleGuide` component

--- src/scripts/styleguide.cjsx
+++ src/scripts/styleguide.cjsx
@@ -4,7 +4,7 @@

 # Simple HTML element styleguide to demonstrate default css stylings.
 module.exports = React.createClass
-  displayName: 'HelloWorld'
+  displayName: 'StyleGuide'

   componentDidMount: ->
     window.scroll(0,0)


Allow to add new tools without duplicating existing

Previously adding new tool in bokehjs caused existing tools to
be duplicated. This commit only handles adding new tool case.
Removed tools are still there and this requires more changes,
which are currently in conflict with two layers of active tool
handling.

--- bokehjs/src/coffee/common/tool_manager.coffee
+++ bokehjs/src/coffee/common/tool_manager.coffee
@@ -76,42 +76,35 @@
   serializable_in_document: () -> false

   _init_tools: () ->
-    gestures = @get('gestures')
-
     for tool in @get('plot').get('tools')
       if tool instanceof InspectTool.Model
-        inspectors = @get('inspectors')
-        inspectors.push(tool)
-        @set('inspectors', inspectors)
-
+        if not _.some(@inspectors, (t) => t.id == tool.id)
+          @inspectors = @inspectors.concat([tool])
       else if tool instanceof HelpTool.Model
-        help = @get('help')
-        help.push(tool)
-        @set('help', help)
-
+        if not _.some(@help, (t) => t.id == tool.id)
+          @help = @help.concat([tool])
       else if tool instanceof ActionTool.Model
-        actions = @get('actions')
-        actions.push(tool)
-        @set('actions', actions)
-
+        if not _.some(@actions, (t) => t.id == tool.id)
+          @actions = @actions.concat([tool])
       else if tool instanceof GestureTool.Model
         et = tool.event_type

-        if et not of gestures
+        if et not of @gestures
           logger.warn("ToolManager: unknown event type '#{et}' for tool:
                       #{tool.type} (#{tool.id})")
           continue

-        gestures[et].tools.push(tool)
+        if not _.some(@gestures[et].tools, (t) => t.id == tool.id)
+          @gestures[et].tools = @gestures[et].tools.concat([tool])
         @listenTo(tool, 'change:active', _.bind(@_active_change, tool))

-    for et of gestures
-      tools = gestures[et].tools
+    for et of @gestures
+      tools = @gestures[et].tools
       if tools.length == 0
         continue
-      gestures[et].tools = _.sortBy(tools, (tool) -> tool.default_order)
+      @gestures[et].tools = _.sortBy(tools, (tool) -> tool.default_order)
       if et not in ['pinch', 'scroll']
-        gestures[et].tools[0].set('active', true)
+        @gestures[et].tools[0].set('active', true)

   _active_change: (tool) =>
     event_type = tool.event_type
@@ -130,19 +123,19 @@
     return null

   @internal {
-    gestures: [ p.Any, () -> {
-      pan: {tools: [], active: null}
-      tap: {tools: [], active: null}
-      doubletap: {tools: [], active: null}
-      scroll: {tools: [], active: null}
-      pinch: {tools: [], active: null}
-      press: {tools: [], active: null}
-      rotate: {tools: [], active: null}
+    gestures:   [ p.Any, () -> {
+      pan:       { tools: [], active: null }
+      tap:       { tools: [], active: null }
+      doubletap: { tools: [], active: null }
+      scroll:    { tools: [], active: null }
+      pinch:     { tools: [], active: null }
+      press:     { tools: [], active: null }
+      rotate:    { tools: [], active: null }
     } ]
-    actions: [ p.Array, [] ]
+    actions:    [ p.Array, [] ]
     inspectors: [ p.Array, [] ]
-    help: [ p.Array, [] ]
-    plot: [ p.Instance ]
+    help:       [ p.Array, [] ]
+    plot:       [ p.Instance ]
   }

 module.exports =


Preload the Next Page of the book

Preload the Next Page of the book

--- src/scripts/modules/media/nav/nav.coffee
+++ src/scripts/modules/media/nav/nav.coffee
@@ -19,7 +19,10 @@
       if page isnt nextPage
         next = linksHelper.getPath('contents', {model: @model, page: nextPage})
         if next isnt undefined
+          urlScheme = window.location.protocol+"//"
           $('head').append("<link rel=\"next\" href=\"#{location.host}#{next}\" />") if next
+          $('link[rel="prerender"]').remove()
+          $('head').append("<link rel=\"prerender\" href=\"#{urlScheme}#{location.host}#{next}\" />") if next

       $('link[rel="prev"]').remove()
       if page isnt previousPage


better log msgs

better log msgs

--- src/scripts/services/dapiServices.coffee
+++ src/scripts/services/dapiServices.coffee
@@ -1,6 +1,6 @@
 class DapiService
-  @$inject: ['$http', '$routeParams']
-  constructor: (@http, routeParams) ->
+  @$inject: ['$log', '$http', '$routeParams']
+  constructor: (@log, @http, routeParams) ->
     useLocalServer = routeParams.localServer ? false
     base = if useLocalServer
       'http://localhost:8080'
@@ -13,16 +13,19 @@
     @apiBase + @endpoint

   get: ->
+    @log.debug("Getting all #{@endpoint}")
     @http.get(@urlBase())
     .then (results) ->
       results.data

   getId: (id) ->
+    @log.debug("Getting #{@endpoint}/#{id}")
     @http.get("#{@urlBase()}/#{id}")
     .then (results) ->
       results.data

   saveId: (id, obj) ->
+    @log.debug("Saving #{@endpoint}/#{id}")
     @http.post("#{@urlBase()}/#{id}", obj)
     .error (results, status) ->
       {results, status}


Reshowing the cursor after the service is selected in case there is an error that causes the process to exit.

--- src/service_selector.coffee
+++ src/service_selector.coffee
@@ -60,6 +60,7 @@
       @selected_index += if key.name == "up" then -1 else +1
       @render()
     if key.name == "enter" and @services.list.length > 0
+      @cursor.show()
       @stop()
       @emit("select", @services.list[@selected_index])


new channel

new channel

--- components/new_channel/client/new_channel_view.coffee
+++ components/new_channel/client/new_channel_view.coffee
@@ -3,6 +3,7 @@
 sd = require("sharify").data
 Channel = require '../../../models/channel.coffee'
 mediator = require '../../../lib/mediator.coffee'
+analytics = require '../../../lib/analytics.coffee'

 ChannelVisibilityView = require '../../channel_visibility/client/channel_visibility_view.coffee'

@@ -58,6 +59,7 @@

     @model.save null,
       success: =>
+        analytics.track.click "New Channel created"
         @$('.grid__block').removeClass 'grid__block--loading'
         document.location.href = "/#{@model.get('user').username}/#{@model.get('slug')}"


link to api docs from account settings

link to api docs from account settings

--- src/smc-webapp/api-key.cjsx
+++ src/smc-webapp/api-key.cjsx
@@ -151,7 +151,7 @@

-            The API is currently undocumented.  Contact support if you need to use this.
+            See the CoCalc API documentation to learn about the API.


images parameter is an object not an array, so we can only compare length once we've converted it to an array

--- src/giphy.coffee
+++ src/giphy.coffee
@@ -147,18 +147,19 @@
       callback(if data.length == 1 then data[0] else data[Math.floor(Math.random() * data.length)])

   getUriFromResultDataWithMaxSize: (images, size = 0, allowLargerThanMaxSize = false) ->
-    if images and images.length and size > 0
+    if images and size > 0
       imagesBySize = Object.keys images
         .map (x) -> images[x]
         .sort (a, b) -> a.size - b.size

-      allowedImages = imagesBySize
-        .filter (x) -> x.size <= size
-
-      if allowedImages and allowedImages.length > 0
-        allowedImages[allowedImages.length - 1]
-      else if allowLargerThanMaxSize
-        imagesBySize[0]
+      if imagesBySize.length > 0
+        allowedImages = imagesBySize
+          .filter (x) -> x.size <= size
+
+        if allowedImages and allowedImages.length > 0
+          allowedImages[allowedImages.length - 1]
+        else if allowLargerThanMaxSize
+          imagesBySize[0]

   getUriFromResultData: (data) ->
     if data and data.images


add hover.mode default value

add hover.mode default value

--- bokehjs/src/coffee/tool/inspectors/hover_tool.coffee
+++ bokehjs/src/coffee/tool/inspectors/hover_tool.coffee
@@ -172,9 +172,8 @@
         ["index",         "$index"]
         ["data (x, y)",   "($x, $y)"]
         ["canvas (x, y)", "($sx, $sy)"]
-
+        mode: 'point'
         hit_value_mode: 'snap_to_data' # 'glyph_center', 'hit_interpolate', 'mouse_point',
-
         point_policy: "snap_to_data" #, "follow_mouse", "none"
         line_policy: "prev" # "next", "nearest", "interp", "none"
         conflict_policy: "line" #, "point", "both"


add postgres no password warning

add postgres no password warning

--- src/smc-hub/postgres-base.coffee
+++ src/smc-hub/postgres-base.coffee
@@ -27,6 +27,7 @@
     try
         return fs.readFileSync(filename).toString().trim()
     catch
+        winston.debug("NO PASSWORD FILE!")
         # no password file
         return


Fix query.

Fix query.

--- src/spec/integration.spec.coffee
+++ src/spec/integration.spec.coffee
@@ -9,11 +9,10 @@
 describe '#run', ->
   beforeEach (done) ->
     @sync = new OrderStateSync Config
-    @channelId = 'TODO'

     ensureChannel = (rest, channelKey, type) ->
       deferred = Q.defer()
-      rest.GET "/channels?query=" + encodeURIComponent("key=\"#{channelKey}\""), (error, response, body) ->
+      rest.GET "/channels?where=" + encodeURIComponent("key=\"#{channelKey}\""), (error, response, body) ->
         if error
           deferred.reject "Error: " + error
           return deferred.promise
@@ -37,6 +36,10 @@
       deferred.promise
     ensureChannel(@sync.sync._rest, 'integrationTest').then (channelId) =>
       @channelId = channelId
+      done()
+    .fail (msg) ->
+      console.log msg
+      expect(false).toBe true
       done()

   it 'Nothing to do', (done) ->


removed reference to easy image

removed reference to easy image

--- test/unit/coffee/FileConverterTests.coffee
+++ test/unit/coffee/FileConverterTests.coffee
@@ -10,13 +10,9 @@

 	beforeEach ->

-		@easyimage =
-			convert:sinon.stub()
-			exec: sinon.stub()
 		@child_process =
 			exec : sinon.stub()
 		@converter = SandboxedModule.require modulePath, requires:
-			"easyimage":@easyimage
 			'child_process': @child_process
 			"logger-sharelatex":
 				log:->
@@ -55,7 +51,7 @@
 				done()

 	describe "thumbnail", ->
-		it "should call easy image resize with args", (done)->
+		it "should call converter resize with args", (done)->
 			@child_process.exec.callsArgWith(2)
 			@converter.thumbnail @sourcePath, (err)=>
 				args = @child_process.exec.args[0][0]
@@ -63,7 +59,7 @@
 				done()

 	describe "preview", ->
-		it "should call easy image resize with args", (done)->
+		it "should call converter resize with args", (done)->
 			@child_process.exec.callsArgWith(2)
 			@converter.preview @sourcePath, (err)=>
 				args = @child_process.exec.args[0][0]


Fix error in highlight region width calculation

--- src/text-editor-presenter.coffee
+++ src/text-editor-presenter.coffee
@@ -1001,8 +1001,7 @@
     @lineHeight? and @baseCharacterWidth?

   pixelPositionForScreenPosition: (screenPosition) ->
-    position =
-      @linesYardstick.pixelPositionForScreenPosition(screenPosition)
+    position = @linesYardstick.pixelPositionForScreenPosition(screenPosition)
     position.top -= @getScrollTop()
     position.left -= @getScrollLeft()

@@ -1225,13 +1224,14 @@
       screenRange.end.column = 0

   repositionRegionWithinTile: (region, tileStartRow) ->
-    region.top  += @scrollTop - @lineTopIndex.pixelPositionBeforeBlocksForRow(tileStartRow)
-    region.left += @scrollLeft
+    region.top += @scrollTop - @lineTopIndex.pixelPositionBeforeBlocksForRow(tileStartRow)

   buildHighlightRegions: (screenRange) ->
     lineHeightInPixels = @lineHeight
     startPixelPosition = @pixelPositionForScreenPosition(screenRange.start)
     endPixelPosition = @pixelPositionForScreenPosition(screenRange.end)
+    startPixelPosition.left += @scrollLeft
+    endPixelPosition.left += @scrollLeft
     spannedRows = screenRange.end.row - screenRange.start.row + 1

     regions = []


Slightly improve algorithm to calculate @endRow

--- src/text-editor-presenter.coffee
+++ src/text-editor-presenter.coffee
@@ -638,7 +638,7 @@

     @endRow = Math.min(
       @model.getScreenLineCount(),
-      @lineTopIndex.rowForPixelPosition(@scrollTop + @height + (2 * @lineHeight - 1))
+      @lineTopIndex.rowForPixelPosition(@scrollTop + @height + @lineHeight - 1) + 1
     )

   updateRowsPerPage: ->


Add kinetic scrolling with edge bouncing when on scroll end.

--- src/traits/ScrollableView.coffee
+++ src/traits/ScrollableView.coffee
@@ -105,6 +105,9 @@
 TICK_INTERVAL = 30

 T_CONST = 325
+
+AMPLITUDE_CONST = 0.55
+MAX_EDGE_VELOCITY = 1000

 ###*
 # Start the view scrolling.
@@ -155,8 +158,21 @@
 stopKineticScrolling = ->
   clearInterval scrollTicker
   if Math.abs(velocity) > 10
-    amplitude = 0.8 * velocity
+
+    amplitude = AMPLITUDE_CONST * velocity
     target = Math.round(offset + amplitude)
+
+    if target < min
+      target = min
+    else if target > max
+      target = max
+
+    if target is min or target is max
+      pv = velocity
+      velocity = Math.min Math.abs(velocity), MAX_EDGE_VELOCITY
+      if pv < 0 then velocity *= -1
+      amplitude = AMPLITUDE_CONST * velocity
+
     scrollTimestamp = Date.now()
     requestAnimationFrame => autoScroll.call @

@@ -165,9 +181,15 @@
   if amplitude
     elapsed = Date.now() - scrollTimestamp
     delta = -amplitude * Math.exp(-elapsed / T_CONST)
+
     if Math.abs(delta) > 0.5
-      console.log target, delta, target + delta
-      scroll.call @, target + delta
+
+      if target is min or target is max
+        t = target - delta
+      else
+        t = target + delta
+
+      scroll.call @, t
       requestAnimationFrame => autoScroll.call @
     else
       scroll.call @, target


oauth: prepend group name to redirection urls

--- workers/social/lib/social/models/oauth.coffee
+++ workers/social/lib/social/models/oauth.coffee
@@ -18,16 +18,18 @@
         {clientId, redirectUri} = KONFIG.github
         {scope, returnUrl} = options
         scope = "user:email"  unless scope
+        redirectUri = @prependGroupName "#{redirectUri}", client.context.group
         redirectUri = "#{redirectUri}?returnUrl=#{returnUrl}"  if returnUrl
         url = "https://github.com/login/oauth/authorize?client_id=#{clientId}&scope=#{scope}&redirect_uri=#{redirectUri}"
         callback null, url
       when "facebook"
         {clientId, redirectUri} = KONFIG.facebook
+        redirectUri = @prependGroupName redirectUri, client.context.group
         url = "https://facebook.com/dialog/oauth?client_id=#{clientId}&redirect_uri=#{redirectUri}"
         callback null, url
       when "google"
         {client_id, redirect_uri} = KONFIG.google
-
+        redirect_uri = @prependGroupName redirect_uri, client.context.group
         url  = "https://accounts.google.com/o/oauth2/auth?"
         url += "scope=https://www.google.com/m8/feeds "
         url += "https://www.googleapis.com/auth/userinfo.profile "
@@ -40,6 +42,7 @@
         callback null, url
       when "linkedin"
         {client_id, redirect_uri} = KONFIG.linkedin
+        redirect_uri = @prependGroupName redirect_uri, client.context.group
         state = crypto.createHash("md5").update((new Date).toString()).digest("hex")

         url  = "https://www.linkedin.com/uas/oauth2/authorization?"
@@ -53,6 +56,11 @@
         @saveTokensAndReturnUrl client, "odesk", callback
       when "twitter"
         @saveTokensAndReturnUrl client, "twitter", callback
+
+  @prependGroupName = (url, groupName) ->
+    protocol = if url.indexOf("https://") is 0 then "https://" else "http://"
+
+    return url.replace protocol, "#{protocol}#{groupName}."

   @saveTokensAndReturnUrl = (client, provider, callback)->
     @getTokens provider, (err, {requestToken, requestTokenSecret, url})=>


uncomment

uncomment

--- client/lib/setup/index.coffee
+++ client/lib/setup/index.coffee
@@ -30,8 +30,8 @@
   Backbone.sync = require 'backbone-super-sync'

   # Mount generic middleware & run setup modules
-  # if 'production' is NODE_ENV
-  #   app.set('forceSSLOptions', { trustXFPHeader: true }).use forceSSL
+  if 'production' is NODE_ENV
+    app.set('forceSSLOptions', { trustXFPHeader: true }).use forceSSL
   app.use sharify
   setupEnv app
   app.use cookieParser()


fixed resize tool issues

fixed resize tool issues

--- static/coffee/common/plot.coffee
+++ static/coffee/common/plot.coffee
@@ -41,23 +41,25 @@
   unpause : (render_canvas=false) ->
     @is_paused = false
     if render_canvas
-      @render_canvas()
-    @request_render()
+      @request_render_canvas(true)
+    else
+      @request_render()

   request_render : () ->
     if not @is_paused
       @throttled_render()
     return

-  request_render_canvas : () ->
+  request_render_canvas : (full_render) ->
     if not @is_paused
-      @render_canvas()
+      @throttled_render_canvas(full_render)
     return

   initialize: (options) ->
     # $('body').mousedown(@_mousedown)
     # $('body').mousemove(@_mousemove)
     @throttled_render = _.throttle(@render, 100)
+    @throttled_render_canvas = _.throttle(@render_canvas, 100)

     @title_props = new text_properties(@, {}, 'title_')

@@ -204,7 +206,8 @@
     @canvas_wrapper = @$el.find('.bokeh_canvas_wrapper')
     @canvas = @$el.find('canvas.bokeh_canvas')

-  render_canvas: () ->
+  render_canvas: (full_render=true) ->
+    console.log("rendercanvas")
     oh = @view_state.get('outer_height')
     ow = @view_state.get('outer_width')

@@ -214,6 +217,8 @@
     @$el.attr("width", ow).attr('height', oh)

     @ctx = @canvas[0].getContext('2d')
+    if full_render
+      @render()

   save_png: () ->
     @render()


Remove debugger from code

Remove debugger from code

--- keypress.coffee
+++ keypress.coffee
@@ -323,7 +323,6 @@
                         match = false
                         break
             if match
-                debugger
                 if combo.is_exclusive
                     @_sequence = []
                 return combo


Remove e.prevendDefault() for React.js compatibility

--- src/index.coffee
+++ src/index.coffee
@@ -176,8 +176,7 @@

   # If '4242' + 4
   if re.test(value)
-    e.preventDefault()
-    QJ.val(target, value + ' ' + digit)
+    QJ.val(target, value + ' ')
     QJ.trigger(target, 'change')

 formatBackCardNumber = (e) ->
@@ -197,9 +196,8 @@
     e.preventDefault()
     QJ.val(target, value.replace(/\d\s$/, ''))
     QJ.trigger(target, 'change')
-  else if /\s\d?$/.test(value)
-    e.preventDefault()
-    QJ.val(target, value.replace(/\s\d?$/, ''))
+  else if /\s\d$/.test(value)
+    QJ.val(target, value.replace(/\d?$/, ''))
     QJ.trigger(target, 'change')

 # Format Expiry


Change Numbo.tools to Numbo.utils, finally

--- src/index.coffee
+++ src/index.coffee
@@ -90,7 +90,7 @@

 # Public methods
 Numbo::convert = convert
-Numbo::tools = utils
+Numbo::utils = utils
 Numbo::enUS = enUS
 Numbo::zhTW = zhTW
 Numbo::zhCN = zhCN


Remove extra white space

Remove extra white space

--- src/index.coffee
+++ src/index.coffee
@@ -95,8 +95,6 @@

     return cb null

-
-
 Image.prototype.resize = (version, cb) ->
   if version.original
     version.src = @src


testing

testing

--- src/index.coffee
+++ src/index.coffee
@@ -35,7 +35,7 @@
       console.log "curentMeeting found : ", currentMeeting
       meetingStartTime = _.get event, 'genisys.currentMeeting.startTime'
       noShowLimit = moment(meetingStartTime).utc().add(@limitMinutes, 'minute')
-      if (moment().isBefore(noShowLimit) && moment(@validUntil).isBefore(@validUntil))
+      if (moment().isBefore(noShowLimit) && moment(@validUntil).isBefore(moment()))
         @validUntil = noShowLimit
         console.log "Initializing valid until to no show limit as : #{@validUntil.toISOString()}"


100ms delay before exit of process

100ms delay before exit of process

--- src/index.coffee
+++ src/index.coffee
@@ -8,7 +8,7 @@
 process.on 'uncaughtException', (err) ->
 	log.error 'Uncaught exception:', err.stack

-	process.nextTick ->
+	Q.delay(100).then ->
 		process.exit 1

 logLevel = argv.log ? 'info'


logging

logging

--- src/index.coffee
+++ src/index.coffee
@@ -13,6 +13,6 @@

 server.start (error) ->
   if error
-    console.log error
+    console.trace error
   else
     console.log 'ce-front-end started'


make @ and backslash partly work in find panel

need to dig into atom to find a better solution, though. because currently the special characters are always attached to the end of the string

--- lib/compatible-view.coffee
+++ lib/compatible-view.coffee
@@ -18,9 +18,16 @@
     @detach()

   at: (event) ->
-    editor = event.targetView().editor
-    editor.insertText('@') if editor
+    debugger
+    view = event.targetView()
+    if view.editor
+        view.editor.insertText('@')
+    else if view
+        view.setText(view.getText()+'@')

   backslash: (event) ->
-    editor = event.targetView().editor
-    editor.insertText('\\') if editor
+    view = event.targetView()
+    if view.editor
+        view.editor.insertText('\\')
+    else if view
+        view.setText(view.getText()+'\\')


Don't assume person always exists.

Don't assume person always exists.

--- lib/documents/group.coffee
+++ lib/documents/group.coffee
@@ -41,9 +41,10 @@
     conditions = super
     return conditions unless _.isArray conditions

-    conditions.push
-      _id:
-        $in: _.pluck person.inGroups, '_id'
+    if person?._id
+      conditions.push
+        _id:
+          $in: _.pluck person.inGroups, '_id'

     conditions


use onDidChange() over onDidStopChanging()

--- lib/edit-in-new-tab.coffee
+++ lib/edit-in-new-tab.coffee
@@ -111,13 +111,9 @@
           childEditor = atom.workspace.getActiveTextEditor().id

           atom.workspace.observeTextEditors (editor) =>
-            if editor.id is parentEditor
-              console.log "editor.id is parentEditor"
-            else if editor.id is childEditor
-              console.log "editor.id is childEditor"
             return unless editor.id is childEditor

-            editor.onDidStopChanging =>
+            editor.onDidChange =>
               parentSelection.insertText(editor.getText(), { select: true })

       .catch (error) ->


select all on filter-text focus restore placeholder

--- lib/go-outline-view.coffee
+++ lib/go-outline-view.coffee
@@ -28,7 +28,7 @@
           @div class: "icon icon-chevron-up", title: "collapse all", outlet: 'btnCollapse'
           @div class: "icon icon-chevron-down", title: "expand all", outlet: 'btnExpand'
         @div class: "go-outline-search", =>
-          @subview 'searchField', new TextEditorView(mini: true)
+          @subview 'searchField', new TextEditorView({mini: true, placeholderText:"filter"})
           @div class: "icon icon-x", outlet: 'btnResetFilter'
       @div class: 'go-outline-tree-scroller order--center', outlet: 'scroller', =>
         @ol class: 'go-outline-tree full-menu list-tree has-collapsable-children focusable-panel', tabindex: -1, outlet: 'list'
@@ -129,6 +129,10 @@
       else if e.keyCode == 27 # pressed ESC
         @resetFilter()

+    editorView.addEventListener 'focus', (e) =>
+      @searchField.getModel().selectAll()
+
+
   searchBuffer: =>
     @searchField.getModel().getBuffer()

@@ -139,7 +143,6 @@

   focusFilter: =>
     @searchField.focus()
-    @searchField.getModel().selectAll()

   applyFilter: =>
     @filterText = @searchBuffer().getText()


fix #24

fix #24

--- lib/go-to-line-view.coffee
+++ lib/go-to-line-view.coffee
@@ -68,6 +68,7 @@
     position = new Point(row, column)
     editor.scrollToBufferPosition(position, center: true)
     editor.setCursorBufferPosition(position)
+    editor.unfoldCurrentRow()
     if column < 0
       editor.moveToFirstCharacterOfLine()


Added comments to the source code to explain each part

--- lethargy.coffee
+++ lethargy.coffee
@@ -2,15 +2,27 @@

 class root.Lethargy
   constructor: (stability, sensitivity, tolerance) ->
+
+    # Stability is how many records to use to calculate the average
     @stability = if stability? then Math.abs stability else 8
+
+    # The wheelDelta threshold. If an event has a wheelDelta below this value, it will not register
     @sensitivity = if sensitivity? then 1 + Math.abs sensitivity else 100
+
+    # How much the old rolling average have to differ from the new rolling average for it to be deemed significant
     @tolerance = if tolerance? then 1 + Math.abs tolerance else 1.1
+
+    # Used internally and should not be manipulated
     @lastUpDeltas = (null for [1..(@stability * 2)])
     @lastDownDeltas = (null for [1..(@stability * 2)])
     @deltasTimestamp = (null for [1..(@stability * 2)])

+  # Checks whether the mousewheel event is an intent
   check: (e) ->
+    # Use jQuery's e.originalEvent if available
     e = e.originalEvent || e
+
+    # Standardise wheelDelta values for different browsers
     if e.wheelDelta?
       lastDelta = e.wheelDelta
     else if e.deltaY?
@@ -18,13 +30,16 @@
     else if (e.detail? or e.detail == 0)
       lastDelta = e.detail * -40

+    # Add the new event timestamp to deltasTimestamp array, and remove the oldest entry
     @deltasTimestamp.push(Date.now())
     @deltasTimestamp.shift()

+    # If lastDelta is positive, it means the user scrolled up
     if (lastDelta > 0)
       @lastUpDeltas.push(lastDelta)
       @lastUpDeltas.shift()
       return @isInertia(1)
+    # Otherwise, the user scrolled down
     else
       @lastDownDeltas.push(lastDelta)
       @lastDownDeltas.shift()
@@ -32,11 +47,18 @@
     false;

   isInertia: (direction) ->
+    # Get the relevant last*Delta array
     lastDeltas = if direction == -1 then @lastDownDeltas else @lastUpDeltas
+
+    # If the array is not filled up yet, we cannot compare averages, so assume the scroll event to be intentional
     if lastDeltas[0] == null
       return direction
+
+    # If the last mousewheel occurred within 150 miliseconds of the penultimate one, and their values are the same. We will assume that this is a trackpad with a constant profile, and will return false
     if @deltasTimestamp[(this.stability * 2) - 2] + 150 > Date.now() and lastDeltas[0] == lastDeltas[(@stability * 2) - 1]
       return false
+
+    # Check to see if the new rolling average (based on the last half of the lastDeltas array) is significantly higher than the old rolling average. If so return direction, else false
     lastDeltasOld = lastDeltas.slice(0, @stability)
     lastDeltasNew = lastDeltas.slice(@stability, (@stability * 2))


More package.json docs cleanup / improvements @zackbloom

--- coffee/formats/package.coffee
+++ coffee/formats/package.coffee
@@ -1,7 +1,7 @@
-depInfo = '''
+depInfo = (propertyName) -> """

The format is "PACKAGE_NAME": "VERSION", for example:

-
{
+
"#{ propertyName }": {
     "coffee-script": "1.6.1",
     "gulp": "~3.6.2"
   }

@@ -9,7 +9,7 @@

Packages can be found using the npm search command, or on npmjs.com.

Version requirements are specified using semver.

-'''
+"""

 context =
   'default': '''
@@ -82,13 +82,16 @@

The url to your project’s issue tracker and / or the email address to which issues should be reported. These are helpful for people who encounter issues with your package.

It should look like this:

-
{
+
+
"bugs": {
       "url": "https://github.com/owner/project/issues",
       "email": "project@hostname.com"
     }

You can specify either one or both values. If you want to provide only a url, you can specify the value for “bugs” as a simple string instead of an object.

+
"bugs": "https://github.com/owner/project/issues"

+

If a url is provided, it will be used by the npm bugs command.

   '''

@@ -99,20 +102,20 @@

If you're using a common license such as BSD-2-Clause or MIT, add a current SPDX license identifier for the license you're using, like this:

-
{ "license": "BSD-3-Clause" }

+
"license": "BSD-3-Clause"

You can check the full list of SPDX license IDs.

If your package is licensed under multiple common licenses, use an SPDX license expression syntax version 2.0 string, like this:

-
{ "license": "(ISC OR GPL-3.0)" }

+
"license": "(ISC OR GPL-3.0)"

If you are using a license that hasn't been assigned an SPDX identifier, or if you are using a custom license, use the following valid SPDX expression:

-
{ "license": "SEE LICENSE IN <filename>" }

+
"license": "SEE LICENSE IN <filename>"

Then include a file named <filename> at the top level of the package.

If you do not wish to grant others the right to use a private or unpublished package under any terms:

-
{ "license": "UNLICENSED" }

+
"license": "UNLICENSED"

   '''

   '(author|contributors)': '''
@@ -176,7 +179,7 @@

The main field informs npm which file should be loaded when a user attempts to require() your package.

-
For example, if your package is called app and you specify the main property as "main.js", when the user runs require('app'), your main.js file will be loaded.

+
For example, if your package is called app and you specify the main property as "main.js", when the user runs require('app'), your main.js file will be loaded.

   '''

   'bin(\.PROPERTY)?': '''
@@ -186,7 +189,7 @@

For example, if you’d like your cli.js file to be executed when the user runs myapp on the command line, you could specify:

-
{ "bin": { "myapp": "./cli.js" } }

+
"bin": { "myapp": "./cli.js" }

If you only have a single executable, and you’d like the command line program to have the same name as your package, you can just specify the file to be executed as a string:

@@ -251,7 +254,7 @@

The command can be any executable:

-
{
+
"scripts": {
       "prepublish": "rm -r build; gulp build"
     }

@@ -278,7 +281,7 @@

Dependencies

Dependencies allow you to specify what other npm packages your code requires, and at which versions.

-  ''' + depInfo
+  ''' + depInfo('dependencies')

   'devDependencies': '''

Dev Dependencies

@@ -286,7 +289,7 @@

Dev dependencies work exactly as dependencies, but they are not installed when a user installs your package without downloading the source (unless they provide the --dev option).

It often makes sense to include build and test tools as dev dependencies, so end users don’t have to install them if their not required to use the package.

-  ''' + depInfo
+  ''' + depInfo('devDependencies')

   'peerDependencies': '''

Peer Dependencies

@@ -294,13 +297,13 @@

If you’re building a plugin which interacts with another package, it’s often valuable to express what versions of that package you support.

Peer dependencies allow you to express this compatibility. Be as broad as you can, as npm will error if the user tries to use your plugin with an incompatible version.

-  ''' + depInfo
+  ''' + depInfo('peerDependencies')

   'optionalDependencies': '''

Optional Dependencies

If a package in dependencies fails to install, the installation of your package will be aborted. If you do not wish this to happen for some dependencies (i.e. your package can run without them), include them as optional dependencies.

-  ''' + depInfo
+  ''' + depInfo('optionalDependencies')

   'engines(\.PROPERTY)?': '''

Engines

@@ -309,7 +312,9 @@

For example:

-
{ "engines": { "node": ">=0.10.3 <0.12" } }

+
"engines": {
+      "node": ">=0.10.3 <0.12"
+    }

   '''

   '(dependencies|optionalDependencies|peerDependencies|devDependencies)\.PROPERTY': '''


Fixed timing on slider bar.

Fixed timing on slider bar.

--- app/assets/javascripts/reservation_popups.js.coffee
+++ app/assets/javascripts/reservation_popups.js.coffee
@@ -51,7 +51,7 @@
   slid: (event, ui) =>
     start = ui.values[0]
     end = ui.values[1]
-    max_reservation = @max_reservation/60/10-1
+    max_reservation = @max_reservation/60/10
     # Don't allow less than 10 minutes.
     if(end-start < 1)
       event.preventDefault()


Fix for update popup not displaying.

Fix for update popup not displaying.

--- app/assets/javascripts/reservation_popups.js.coffee
+++ app/assets/javascripts/reservation_popups.js.coffee
@@ -120,11 +120,11 @@
     result.pop() if result.length > 3
     "#{result.join("-").replace("Z","")}-00:00"
   position_popup: (x, y)->
-    @popup.show()
     if(y < window.scrollY)
       y = window.scrollY+10
     # Change behavior for phones
     @popup.attr("style","")
+    @popup.show()
     if $("body").width() <= 480
       @popup.css("max-width","none")
       @popup.css("max-height","none")


Fixed mensinda's last commit

Fixed mensinda's last commit

--- lib/atox.coffee
+++ lib/atox.coffee
@@ -57,7 +57,7 @@
     @event         = new Emitter
     @mainWin       = new MainWindow    @event
     @notifications = new Notifications @event
-    @TOX           = new ToxWorker     {dll: "#{__dirname}\\bin\\libtoxcore.dll", event: @event}
+    @TOX           = new ToxWorker     {dll: "#{__dirname}\\..\\bin\\libtox.dll", event: @event}
     @term          = new Terminal      {cid: -2, event: @event}
     @github        = new Github


Avoid error with null images in story-info

--- app/frontend/javascripts/views/story-info.js.coffee
+++ app/frontend/javascripts/views/story-info.js.coffee
@@ -39,9 +39,8 @@
         id:           @model.get('id')
         name:         @model.get('name')
         description:  @model.get('description')
-        image:        @model.get('image').huge.url
+        image:        if @model.get('image') then @model.get('image').huge.url else null
         edit:         @edit
-        #image: if @node.get('image') then @node.get('image').huge.url else null
       }
       @$el.find('.panel-body .index-content, .panel-heading .index-header').addClass 'hide'
       @$el.find('.panel-body .chapter-content, .panel-heading .chapter-header').removeClass 'hide'


Make sure to return all queried inventory entries

--- src/coffee/marketplace-stock-updater.coffee
+++ src/coffee/marketplace-stock-updater.coffee
@@ -55,7 +55,7 @@
         Qutils.processList currentRetailerSKUs, (retailerSKUs) =>
           @logger?.debug "Processing #{_.size retailerSKUs} retailer SKUs"

-          ieRetailer = @retailerClient.inventoryEntries.whereOperator('or')
+          ieRetailer = @retailerClient.inventoryEntries.all().whereOperator('or')
           _.each retailerSKUs, (sku) -> ieRetailer.where("sku = \"#{sku}\"")
           ieRetailer.fetch()
           .then (result) =>
@@ -71,7 +71,7 @@
             @logger?.debug mappedInventoryEntries, "#{_.size mappedInventoryEntries} inventory entries are ready to be processed"
             return Q() if _.size(mappedInventoryEntries) is 0

-            ieMaster = @masterClient.inventoryEntries.whereOperator('or')
+            ieMaster = @masterClient.inventoryEntries.all().whereOperator('or')
             _.each mappedInventoryEntries, (entry) -> ieMaster.where("sku = \"#{entry.sku}\"")
             ieMaster.fetch()
             .then (result) =>


koding-payment: properly revive booleans

use less wonky casting technique for last four of credit card

--- node_modules_koding/koding-payment/lib/models.coffee
+++ node_modules_koding/koding-payment/lib/models.coffee
@@ -8,6 +8,7 @@
     switch o.$?.type
       when 'integer'  then [o._ | 0]
       when 'datetime' then [new Date o._]
+      when 'boolean'  then [if o._ is 'true' then yes else no]
       # TODO: implement any other revivers for the recurly API
       else obj
   else obj
@@ -148,6 +149,7 @@

     if @status in ['success', 'void']
       billing     = xmlJs.details[0].account[0].billing_info[0]
+
       @owner      = "#{ billing.first_name[0] } #{ billing.last_name[0] }"
       @cardType   = billing.card_type[0]
-      @cardNumber = "#{ billing.last_four }"
+      @cardNumber = billing.last_four[0]


Grim-ify depreciated method

Grim-ify depreciated method

--- lib/main.coffee
+++ lib/main.coffee
@@ -98,7 +98,5 @@
   # Depreciated method associated with previous Services API
   # versioning that matched package version.
   legacyProvideStatusBar: ->
-    addLeftTile: @statusBar.addLeftTile.bind(@statusBar)
-    addRightTile: @statusBar.addRightTile.bind(@statusBar)
-    getLeftTiles: @statusBar.getLeftTiles.bind(@statusBar)
-    getRightTiles: @statusBar.getRightTiles.bind(@statusBar)
+     Grim.deprecate("Use at least version 1.0.0 of status-bar Service API.")
+     provideStatusBar()


Add lns to Links command names

Add lns to Links command names

--- src/links.coffee
+++ src/links.coffee
@@ -8,7 +8,7 @@

 module.exports =
 class Links
-  @commandNames: ['linked', 'links']
+  @commandNames: ['linked', 'links', 'lns']

   constructor: ->
     @devPackagesPath = path.join(config.getAtomDirectory(), 'dev', 'packages')


Don't separate var list with commas.

Don't separate var list with commas.

--- src/nodes.coffee
+++ src/nodes.coffee
@@ -274,7 +274,7 @@
         code += '\n' if i
         code += "#{@tab}(var "
         if declars
-          code += scope.declaredVariables().join ', '
+          code += scope.declaredVariables().join ' '
         if assigns
           code += ",\n#{@tab + TAB}" if declars
           code += scope.assignedVariables().join ",\n#{@tab + TAB}"