Migrated localstorage to Node CommonJS

Migrated localstorage to Node CommonJS

--- source/micro.localstorage.coffee
+++ source/micro.localstorage.coffee
@@ -1,65 +1,60 @@
-do ->
-  'use strict'
+'use strict'

-  u = module.exports.u if typeof module isnt 'undefined'
-  u = window.u if typeof window isnt 'undefined'
-  u = {} if typeof u is 'undefined'
+_filter = (obj, predicate) ->
+  result = []
+  result.push(item) for item in obj when predicate item
+  result

-  _filter = (obj, predicate) ->
-    result = []
-    result.push(item) for item in obj when predicate item
-    result
+_filterOne = (obj, predicate) ->
+  return item for item in obj when predicate item
+  false

-  _filterOne = (obj, predicate) ->
-    return item for item in obj when predicate item
-    false
+_matches = (attrs) ->
+  (obj) ->
+    return false for key, val of attrs when attrs[key] isnt obj[key]
+    true

-  _matches = (attrs) ->
-    (obj) ->
-      return false for key, val of attrs when attrs[key] isnt obj[key]
-      true
+localDB =
+  data: {}

-  u.db =
-    data: {}
+  _checkCollection: (collection) ->
+    @data[collection] = if @data[collection] then @data[collection] else []

-    _checkCollection: (collection) ->
-      @data[collection] = if @data[collection] then @data[collection] else []
+  get: (collection) ->
+    if localStorage.getItem collection
+      @data[collection] = JSON.parse localStorage.getItem(collection)

-    get: (collection) ->
-      if localStorage.getItem collection
-        @data[collection] = JSON.parse localStorage.getItem(collection)
+  clear: (collection) ->
+    delete @data[collection]
+    localStorage.removeItem collection

-    clear: (collection) ->
-      delete @data[collection]
-      localStorage.removeItem collection
+  write: (collection) ->
+    localStorage.setItem collection, JSON.stringify @data[collection]

-    write: (collection) ->
-      localStorage.setItem collection, JSON.stringify @data[collection]
+  save: (collection, data) ->
+    items = @_checkCollection collection
+    items.push data
+    @write collection
+    data

-    save: (collection, data) ->
-      items = @_checkCollection collection
-      items.push data
-      @write collection
-      data
+  findOne: (collection, attrs) ->
+    _filterOne @data[collection], _matches attrs if @data[collection]

-    findOne: (collection, attrs) ->
-      _filterOne @data[collection], _matches attrs if @data[collection]
+  find: (collection, attrs) ->
+    _filter @data[collection], _matches attrs if @data[collection]

-    find: (collection, attrs) ->
-      _filter @data[collection], _matches attrs if @data[collection]
+  update: (collection, key, value, attrs) ->
+    items = @_checkCollection collection
+    items.push attrs if items.length is 0
+    data = item for item in items when item[key] is value
+    data[key] = val for key, val of attrs
+    @write collection
+    data

-    update: (collection, key, value, attrs) ->
-      items = @_checkCollection collection
-      items.push attrs if items.length is 0
-      data = item for item in items when item[key] is value
-      data[key] = val for key, val of attrs
-      @write collection
-      data
+  remove: (collection, key, value) ->
+    items = @_checkCollection collection
+    index = items.indexOf item for item in items when item[key] is value
+    items.splice index, 1 if index > -1
+    @write collection

-    remove: (collection, key, value) ->
-      items = @_checkCollection collection
-      index = items.indexOf item for item in items when item[key] is value
-      items.splice index, 1 if index > -1
-      @write collection
-
-  u+module.exports = localDB


test for li passes

test for li passes

--- code/li.coffee
+++ code/li.coffee
@@ -1,7 +1,7 @@
 #!/usr/bin/env coffee

-main = (args) ->
+exports.main = (args) ->
     if args?
-        args = sys.argv()
+        args = process.argv

-main()
+exports.main()


Rewatching files more liberally and consistently

--- command.coffee
+++ command.coffee
@@ -174,35 +174,40 @@

   prevStats = null
   compileTimeout = null
+  rewatchTimeout = null

   watchErr = (e) ->
     if e.code is 'ENOENT'
       return if sources.indexOf(source) is -1
-      removeSource source, base, yes
-      compileJoin()
+      clearTimeout rewatchTimeout
+      rewatchTimeout = wait 25, ->
+        try
+          rewatch()
+          compile()
+        catch e
+          removeSource source, base, yes
+          compileJoin()
     else throw e
+
+  rewatch = ->
+    watcher?.close()
+    watcher = fs.watch source, compile

   compile = ->
     clearTimeout compileTimeout
     compileTimeout = wait 25, ->
       fs.stat source, (err, stats) ->
         return watchErr err if err
-        return if prevStats and (stats.size is prevStats.size and
+        return rewatch() if prevStats and (stats.size is prevStats.size and
           stats.mtime.getTime() is prevStats.mtime.getTime())
         prevStats = stats
         fs.readFile source, (err, code) ->
           return watchErr err if err
           compileScript(source, code.toString(), base)
+          rewatch()

   try
-    watcher = fs.watch source, callback = (event) ->
-      compile()
-      wait 250, ->
-        try
-          watcher.close()
-          watcher = fs.watch source, callback
-        catch e
-          watchErr e
+    watcher = fs.watch source, compile
   catch e
     watchErr e


cant do html tags, so just give links

cant do html tags, so just give links


Fix js error on merge request page

Fix js error on merge request page

Signed-off-by: Dmitriy Zaporozhets <be23d75b156792e5acab51b196a2deb155d35d6a@gmail.com>

--- app/assets/javascripts/merge_request.js.coffee
+++ app/assets/javascripts/merge_request.js.coffee
@@ -10,7 +10,6 @@
   #   action - String, current controller action
   #
   constructor: (@opts) ->
-    @initContextWidget()
     this.$el = $('.merge-request')

     this.$('.show-all-commits').on 'click', =>


use urlRoot

use urlRoot

--- app/assets/javascripts/models/action.js.coffee
+++ app/assets/javascripts/models/action.js.coffee
@@ -2,8 +2,7 @@
 namespace 'Bixby.model', (exports, top) ->

   class exports.Action extends Stark.Model
-    url: ->
-      "/rest/actions"
+    urlRoot: "/rest/actions"

   class exports.ActionList extends Stark.Collection
     model: exports.Action


add ability to include more logic-mapping info.

--- app/assets/javascripts/plugins/graph.js.coffee
+++ app/assets/javascripts/plugins/graph.js.coffee
@@ -21,9 +21,10 @@
     links[node.id] = nodes.length - 1
   edges = []
   for edge in data.edges
-    edges.push(
+    edges.push
       source: links[edge.source_id]
-      target: links[edge.target_id])
+      target: links[edge.target_id]
+      info: edge
   [nodes,edges]

 nodeDisplayName = (node) ->
@@ -105,6 +106,8 @@
       "
Mapping: "+
       "#{path_data.source.info.name} --> "+
       "#{path_data.target.info.name}
"+
+      "
exactness: #{path_data.info.exactness}
"+
+      "
faithfulness: #{path_data.info.faithfulness}
"+
       "
")

   node.append("circle").


Improve test cases on high-DPI device

Improve test cases on high-DPI device

--- spec/minimap-element-spec.coffee
+++ spec/minimap-element-spec.coffee
@@ -15,7 +15,7 @@
   transform = new WebKitCSSMatrix window.getComputedStyle(o).transform
   o.offsetLeft + transform.m41

-devicePixelRatio = 1
+devicePixelRatio = 2

 sleep = (duration) ->
   t = new Date
@@ -29,7 +29,7 @@
     atom.config.set 'minimap.charWidth', 2
     atom.config.set 'minimap.interline', 1
     atom.config.set 'minimap.textOpacity', 1
-    atom.config.set 'minimap.devicePixelRatio', 1
+    atom.config.set 'minimap.devicePixelRatio', 2

     MinimapElement.registerViewProvider()

@@ -720,7 +720,7 @@
           runs -> nextAnimationFrame()

         it 'adjusts the size of the control div to fit in the minimap', ->
-          expect(controls.clientWidth).toEqual(minimapElement.canvas.clientWidth)
+          expect(controls.clientWidth).toEqual(minimapElement.canvas.clientWidth / devicePixelRatio)

         it 'positions the controls div over the canvas', ->
           controlsRect = controls.getBoundingClientRect()
@@ -734,7 +734,7 @@
             nextAnimationFrame()

           it 'adjusts the size of the control div to fit in the minimap', ->
-            expect(controls.clientWidth).toEqual(minimapElement.canvas.clientWidth)
+            expect(controls.clientWidth).toEqual(minimapElement.canvas.clientWidth / devicePixelRatio)

           it 'positions the controls div over the canvas', ->
             controlsRect = controls.getBoundingClientRect()


tests semantic improved

tests semantic improved

--- specs/KataPokerHands.spec.coffee
+++ specs/KataPokerHands.spec.coffee
@@ -1,21 +1,25 @@
 Poker = require('../KataPokerHands')

-describe('should be tie', () ->
-    expect(Poker.compare_hands('Black: 2H 3D 5S 9C KD '
-                              +' White: 2D 3H 5C 9S KH')).toEqual('Tie.')
+describe('Result', () ->
+
+    it('should be tie', () ->
+        expect(Poker.compare_hands('Black: 2H 3D 5S 9C KD '+
+                                   ' White: 2D 3H 5C 9S KH')).toEqual('Tie.')
+    )
+
+    it("should be a White's winning, with high card: Ace", () ->
+        expect(Poker.compare_hands('Black: 2H 3D 5S 9C KD '+
+                                   ' White: 2C 3H 4S 8C AH')).toEqual('White wins. - with high card: Ace')
+    )
+
+    it("should be a White's winning, with flask", () ->
+        expect(Poker.compare_hands('Black: 2H 4S 4C 2D 4H '+
+                                   ' White: 2S 8S AS QS 3S')).toEqual('White wins. - with flash')
+    )
+
+    it("should be a Black's winning with high card: 9", () ->
+        expect(Poker.compare_hands('Black: 2H 3D 5S 9C KD '+
+                                   ' White: 2C 3H 4S 8C KH')).toEqual('Black wins. - with high card: 9')
+    )
+
 )
-
-describe('White should win with high card: Ace', () ->
-    expect(Poker.compare_hands('Black: 2H 3D 5S 9C KD '
-                              +' White: 2C 3H 4S 8C AH')).toEqual('White wins. - with high card: Ace')
-)
-
-describe('White should win with flask', () ->
-    expect(Poker.compare_hands('Black: 2H 4S 4C 2D 4H '
-                              +' White: 2S 8S AS QS 3S')).toEqual('White wins. - with flash')
-)
-
-describe('Black should win with high card: 9', () ->
-    expect(Poker.compare_hands('Black: 2H 3D 5S 9C KD '
-                              +' White: 2C 3H 4S 8C KH')).toEqual('Black wins. - with high card: 9')
-)


stopImmediatePropagation after ditto

stopImmediatePropagation after ditto

--- app/controllers/TranscriptionController.coffee
+++ app/controllers/TranscriptionController.coffee
@@ -56,9 +56,11 @@
       if e.which is 8 and not (e.target.tagName is 'INPUT')
         e.preventDefault()
       else if e.which is 80 and e.ctrlKey and $(".ui-autocomplete:visible").length == 0
+		# ditto functionality
         $(".ui-autocomplete-input").first().autocomplete("search","")
         $(".ui-autocomplete > li").parent().css("width", $(".ui-autocomplete-input").first().css("width"));
         $(".ui-autocomplete > li").parent().css("padding", "0px");
+        e.stopImmediatePropagation()
         e.preventDefault()
       else if $(".ui-autocomplete:visible").length > 0
       	# if menu is open and we press any key that has no meaning for jquery autocomplete menus (arrows, enter, escape, etc), close the menu
@@ -76,4 +78,4 @@
     Spine.unbind 'skipTranscription'
     $(document).off 'keydown.nfn keypress.nfn'

-module.exports = TranscriptionController+module.exports = TranscriptionController


httpClientのテスト実行するためにtest/tests.coffeeのテスト対象を切りかえる

--- coffee/test/tests.coffee
+++ coffee/test/tests.coffee
@@ -9,7 +9,8 @@
   Ti.include('lib/jasmine-1.3.1.js')
   Ti.include('lib/jasmine.async.min.js')
   require('lib/jasmine-titanium-console')
-  require('test/TiCaching')
+  # require('test/TiCaching')
+  require('test/httpClient')

   jasmine.getEnv().addReporter(new jasmine.TitaniumReporter())


FIX - removed old native +iPAd hack no longer needed

--- source/Art/Engine/Core/CanvasElement.coffee
+++ source/Art/Engine/Core/CanvasElement.coffee
@@ -162,13 +162,6 @@
           height = clientHeight

         else if innerWidth > 0 && innerHeight > 0
-          # SUPER HACK - I think this is a bug with cordova-plugin-wkwebview-engine/
-          # randomly, mostly on load, innerHeight gets stuck at the wrong height.
-          # Rotate the iPad and it's fine.
-          if nativeAppDetect() && iOSDetect()
-            unless iPadDetect() && innerHeight != height - 20
-              innerHeight = height
-
           width = innerWidth
           height = innerHeight


Revert accidentally-committed stray typing.

Oops.

--- js/inner/build.coffee
+++ js/inner/build.coffee
@@ -411,7 +411,7 @@
       estimate_is_not_too_low = current_build_millis < estimated_millis * 1.5
       estimate_is_positive = estimated_millis > 0

-      return estimate_is_positive and esXbtimate_is_not_too_low
+      return estimate_is_positive and estimate_is_not_too_low

     if @previous_successful_build()?
       estimated_millis = @previous_successful_build().build_time_millis


change interval

change interval

--- atmospheric/002-accumulated-heat/csmain.coffee
+++ atmospheric/002-accumulated-heat/csmain.coffee
@@ -82,6 +82,6 @@
                 viewer.paint(transformer.target(frame, (time / planet.period)), map, data)
             counter = (counter + 1) % 30
             time += tao
-        handle = setInterval(evolve, 33)
+        handle = setInterval(evolve, 1000)

        true


Random tester can generate conditional expressions


Refactor initModules method

Refactor initModules method

--- lib/assets/javascript/init.js.coffee
+++ lib/assets/javascript/init.js.coffee
@@ -38,20 +38,21 @@
     if typeof view is 'function'
       return new view()
     else if typeof view is 'object'
-      this.initModules(view)
+      @initModules(view)
       return new view.init() if typeof view.init is 'function'

-  initModules: (view)->
-    if view.modules?
-      App.currentModules = [] unless App.currentModules?
+  initModules: (obj)->
+    if obj? and obj.modules?
+      @App.currentModules = [] unless @App.currentModules?

-      if typeof view.modules is 'function'
-        modules = [].concat(new view.modules())
+      if typeof obj.modules is 'function'
+        modules = [].concat(new obj.modules())
       else
-        modules = [].concat(view.modules)
+        modules = [].concat(obj.modules)

       for module in modules
-        App.currentModules.push this.initView(module)
+        @App.currentModules.push @initView(module)
+
   config: (name)->
     @App.configs = { turbolinks: true, pjax: false } unless @App.configs
     return @App.configs[name] if @App.configs and @App.configs[name]


jenkins-notifyのrepositoryのURLの表現をboldなしに変更

--- jenkins-notify.coffee
+++ jenkins-notify.coffee
@@ -102,7 +102,7 @@
   msg.push("elapsed time: #{diff}");
   msg.push("")
   msg.push("project: #{@sm.bold(data['name'])}")
-  msg.push("repository: #{@sm.bold(encodeURI(data['build']['scm']['url']))}")
+  msg.push("repository: #{encodeURI(data['build']['scm']['url'])}")
   msg.push("branch: #{@sm.bold(data['build']['scm']['branch'])}")
   msg.push("commit: #{@sm.bold(commit)}")


Fix: remove reference to TentAdmin

Fix: remove reference to TentAdmin

--- lib/assets/javascripts/models/basic_profile.js.coffee
+++ lib/assets/javascripts/models/basic_profile.js.coffee
@@ -50,7 +50,7 @@
     return setDefaultAvatar() unless value && value.length
     return setDefaultAvatar() unless avatar_attachment = _.find value, (attachment) =>
       attachment.category == 'avatar'
-    url = TentAdmin.tent_client.getNamedUrl('attachment',
+    url = TentStatus.tent_client.getNamedUrl('attachment',
       entity: @get('entity')
       digest: avatar_attachment.digest
     )


Fix failing test

Fix failing test

--- lib/iridium/casperjs/lib/iridium/qunit_adapter.coffee
+++ lib/iridium/casperjs/lib/iridium/qunit_adapter.coffee
@@ -67,7 +67,7 @@
   document.body.insertBefore container, document.body.firstChild

   fixture = document.createElement('div')
-  container.setAttribute "id", "qunit-fixture"
+  fixture.setAttribute "id", "qunit-fixture"
   document.body.insertBefore fixture, document.body.firstChild

   QUnit.load()


Fixing SO poller

Fixing SO poller

--- scripts/stackoverflow-poller.coffee
+++ scripts/stackoverflow-poller.coffee
@@ -8,7 +8,7 @@
 Poller = require '../support/poller'

 PROD_MODE        = process.env.NODE_ENV is 'production'
-POLL_INTERVAL    = 1000 * 60 * 30 # 15 minute interval to start with
+POLL_INTERVAL    = 1000 * 60 * 30
 ANNOUNCE_ROOMS   = []

 do =>
@@ -32,7 +32,8 @@
     @recentIds = []

   pollForNewThreads: ->
-    @poller.start (threads) => @newThreadsCallback.call(this, threads)
+    @poller.start (res) =>
+      @newThreadsCallback.call(this, res.items)

   stop: ->
     @poller.stop()


Implementing histogramThreshold instead of histogram

--- src/d3.timeslider.coffee
+++ src/d3.timeslider.coffee
@@ -456,38 +456,45 @@
         )

     drawRanges: (datasetElement, dataset, records) ->
-        datasetElement.selectAll('rect').remove()
-
-        r = datasetElement.selectAll('rect')
+        rect = (elem) =>
+            elem.attr('class', 'record')
+                .attr('x', (record) => @scales.x(new Date(record[0])) )
+                .attr('y', - (@options.ticksize + 3) * dataset.index + -(@options.ticksize-2) )
+                .attr('width', (record) => @scales.x(new Date(record[1])) - @scales.x(new Date(record[0])) )
+                .attr('height', (@options.ticksize-2))
+                .attr('stroke', d3.rgb(dataset.color).darker())
+                .attr('stroke-width', 1)
+
+        r = datasetElement.selectAll('rect.record')
             .data(records)
+            .call(rect)

         r.enter().append('rect')
-            .attr('x', (record) => @scales.x(new Date(record[0])) )
-            .attr('y', - (@options.ticksize + 3) * dataset.index + -(@options.ticksize-2) )
-            .attr('width', (record) => @scales.x(new Date(record[1])) - @scales.x(new Date(record[0])) )
-            .attr('height', (@options.ticksize-2))
-            .attr('stroke', d3.rgb(dataset.color).darker())
-            .attr('stroke-width', 1)
+            .call(rect)
             .call((recordElement) => @setupRecord(recordElement, dataset))

         r.exit().remove()

     drawPoints: (datasetElement, dataset, records) ->
-        datasetElement.selectAll('circle').remove()
-        p = datasetElement.selectAll('circle')
+        circle = (elem) =>
+            elem.attr('class', 'record')
+                .attr('cx', (a) =>
+                    if Array.isArray(a)
+                        return @scales.x(new Date(a[0]))
+                    else
+                        return @scales.x(new Date(a))
+                )
+                .attr('cy', - (@options.ticksize + 3) * dataset.index - (@options.ticksize - 2) / 2)
+                .attr('stroke', d3.rgb(dataset.color).darker())
+                .attr('stroke-width', 1)
+                .attr('r', @options.ticksize / 2)
+
+        p = datasetElement.selectAll('circle.record')
             .data(records)
+            .call(circle)

         p.enter().append('circle')
-            .attr('cx', (a) =>
-                if Array.isArray(a)
-                    return @scales.x(new Date(a[0]))
-                else
-                    return @scales.x(new Date(a))
-            )
-            .attr('cy', - (@options.ticksize + 3) * dataset.index - (@options.ticksize - 2) / 2)
-            .attr('stroke', d3.rgb(dataset.color).darker())
-            .attr('stroke-width', 1)
-            .attr('r', @options.ticksize / 2)
+            .call(circle)
             .call((recordElement) => @setupRecord(recordElement, dataset))

         p.exit().remove()
@@ -586,20 +593,25 @@
         if not dataset
             return

-        records = dataset.getRecords()
+        [low, high] = @scales.x.domain()
+
+        records = (dataset.getRecords() || [])
+            .filter((r) -> r[0] <= high and r[1] >= low)
         paths = dataset.getPaths()
         index = dataset.index
         color = dataset.color

         if paths and paths.length
             @drawPaths(dataset.element, dataset, paths)
-        else if records and records.length
-            data = records.map((record) =>
-                new Date(record[0] + (record[1] - record[0]) / 2)
-            )
-            if dataset.histogram
+        else
+            if dataset.histogramThreshold? and records.length >= dataset.histogramThreshold
+                dataset.element.selectAll('.record').remove()
+                data = records.map((record) =>
+                    new Date(record[0] + (record[1] - record[0]) / 2)
+                )
                 @drawHistogram(dataset.element, dataset, records)
             else
+                dataset.element.selectAll('.bin').remove()
                 points = records.filter((record) =>
                     (@scales.x(new Date(record[1])) - @scales.x(new Date(record[0]))) < 5
                 )
@@ -759,7 +771,7 @@
             debounceTime: @options.debounce,
             ordinal: @ordinal,
             element: element,
-            histogram: definition.histogram
+            histogramThreshold: definition.histogramThreshold
         })

         @reloadDataset(id)
@@ -864,7 +876,7 @@
 # Dataset utility class for internal use only
 class Dataset
     constructor: (options) ->
-        { @id,  @color, @source, @sourceParams, @index, @records, @paths, @lineplot, @ordinal, @element, @histogram } = options
+        { @id,  @color, @source, @sourceParams, @index, @records, @paths, @lineplot, @ordinal, @element, @histogramThreshold } = options
         @syncDebounced = debounce(@sync, options.debounceTime)

     getSource: ->


fix(activity-bar): Fix activity bar resizing

--- internal_packages/inbox-activity-bar/lib/activity-bar.cjsx
+++ internal_packages/inbox-activity-bar/lib/activity-bar.cjsx
@@ -35,8 +35,8 @@
   render: ->
     <ResizableRegion className="activity-bar"
                      initialHeight={@state.height}
-                     handle={ResizableRegion.Handle.Top}
-                     onResize={@_onTrayResized}>
+                     minHeight={ActivityBarClosedHeight}
+                     handle={ResizableRegion.Handle.Top}>

         {@_caret()}

@@ -140,10 +140,6 @@
     @setState(section: section)
     @_onShow()

-  _onTrayResized: (height) ->
-    height = ActivityBarClosedHeight if height < 80
-    @setState(height: height)
-
   _onFeedback: ->
     user = NamespaceStore.current().name


button: optional onclick prop

button: optional onclick prop

--- button/index.coffee
+++ button/index.coffee
@@ -52,11 +52,12 @@
       isActive: false
     }

-  render: ({$children}) =>
+  render: ({$children, onclick}) =>
     # TODO: remove $children constructor support
     $children ?= @state.getValue().$children
-    {onclick, type, isDisabled, isRaised, color,
+    {type, isDisabled, isRaised, color,
       isHovered, isActive} = @state.getValue()
+    onclick ?= @state.getValue().onclick
     unless _.isArray $children
       $children = [$children]


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/engine_levels.coffee
+++ src/engine_levels.coffee
@@ -48,7 +48,7 @@
   Load map named level

-  engine.goToLevel()
+  engine.goToLevel('')

   @name nextLevel


Bug fixes

Bug fixes

--- convert.coffee
+++ convert.coffee
@@ -1,12 +1,25 @@
-#!/usr/bin/env node
+#!/usr/bin/env coffee
+
+# TODO:
+#   partials (crawl and map directory this script gets pointed to)
+#   flask server render whole app backend a page at a time
+#   angular hook into page post-render
+
 argv = require('optimist').argv
 fs = require 'fs'

-file = fs.readFileSync argv.file, 'utf8'
+if argv.file
+  file = fs.readFileSync argv.file, 'utf8'
+else
+  console.warn 'you must specify a file with "--file="'
+  return

 selfClosingTags = 'area, base, br, col, command, embed, hr, img, input,
 keygen, link, meta, param, source, track, wbr'.split /,\s*/

+# TODO: pretty format
+#   replace '\n' with '\n  ' where '  ' is 2 spaces * depth
+#   Maybe prettify at very end instead
 getCloseTag = (string) ->
   index = 0
   depth = 0
@@ -49,12 +62,13 @@

 interpolated = file
   .replace(/<[^>]*?ng\-repeat="(.*?)">([\S\s]+)/gi, (match, text, post) ->
-    varName = text.split(' in ')[1]
+    varName = text
+    # varName = text.split(' in ')[1]
     close = getCloseTag match
     if close
-      "{{##{varName}}}\n#{close.before}\n{{/#{varName}}}\n#{close.after}"
+      "{{#each #{varName}}}\n#{close.before}\n{{/each}}\n#{close.after}"
     else
-      throw new Error 'Parse error! Coudlnt find close tag for ng-repeat'
+      throw new Error 'Parse error! Could not find close tag for ng-repeat'
   )
   .replace(/<[^>]*?ng\-if="(.*)".*?>([\S\s]+)/, (match, varName, post) ->
     # Unless
@@ -62,29 +76,29 @@
       varName = varName.substr 1
       close = getCloseTag match
       if close
-        "{{##{varName}}}\n#{close.before}\n{{/#{varName}}}\n#{close.after}"
+        "{{#unless #{varName}}}\n#{close.before}\n{{/unless}}\n#{close.after}"
       else
-        throw new Error 'Parse error! Coudlnt find close tag for ng-repeat'
+        throw new Error 'Parse error! Could not find close tag for ng-if'
     else
       close = getCloseTag match
       if close
-        "{{##{varName}}}\n#{close.before}\n{{/#{varName}}}\n#{close.after}"
+        "{{#if #{varName}}}\n#{close.before}\n{{/if}}\n#{close.after}"
       else
-        throw new Error 'Parse error! Coudlnt find close tag for ng-repeat'
+        throw new Error 'Parse error! Could not find close tag for ng-if'
   )
-  .replace(/<[^>]*?ng\-show="(.*)".*?>([\S\s]+)/g, (match, varName, post) ->
-    close = getCloseTag match
-    if close
-      "{{##{varName}}}\n#{close.before}\n{{/#{varName}}}\n#{close.after}"
-    else
-      throw new Error 'Parse error! Coudlnt find close tag for ng-repeat'
-  )
-  .replace(/<[^>]*?ng\-hide="(.*)".*?>([\S\s]+)/g, (match, varName, post) ->
-    close = getCloseTag match
-    if close
-      "{{##{varName}}}\n#{close.before}\n{{/#{varName}}}\n#{close.after}"
-    else
-      throw new Error 'Parse error! Coudlnt find close tag for ng-repeat'
-  )
+  # .replace(/<[^>]*?ng\-show="(.*)".*?>([\S\s]+)/g, (match, varName, post) ->
+  #   close = getCloseTag match
+  #   if close
+  #     "{{#if #{varName}}}\n#{close.before}\n{{/if}}\n#{close.after}"
+  #   else
+  #     throw new Error 'Parse error! Could not find close tag for ng-show'
+  # )
+  # .replace(/<[^>]*?ng\-hide="(.*)".*?>([\S\s]+)/g, (match, varName, post) ->
+  #   close = getCloseTag match
+  #   if close
+  #     "{{#unless #{varName}}}\n#{close.before}\n{{/unless}}\n#{close.after}"
+  #   else
+  #     throw new Error 'Parse error! Could not find close tag for ng-hide'
+  # )

 console.log '\n\n\n\n\n\n\NINTERPOLATED:\n\n', interpolated


Reset collection

Reset collection

--- django/bb_chat/assets/scripts/views.coffee
+++ django/bb_chat/assets/scripts/views.coffee
@@ -33,7 +33,7 @@
   template: compileTemplate 'conversation-list'

   initialize: =>
-    @listenTo @collection, 'update', @render
+    @listenTo @collection, 'reset', @render
     return

   render: =>
@@ -115,7 +115,7 @@
   initialize: =>
     @conversationListView = new ConversationListView
       collection: new models.Conversations
-    @conversationListView.collection.fetch()
+    @conversationListView.collection.fetch reset: true
     return

   render: =>


Adapted categories somewhat to generic, yet usable, standards

--- config/categories.coffee
+++ config/categories.coffee
@@ -4,22 +4,56 @@
   ships.

   It's recommended that you don't mess with these, because if someone uploads
-  Torrents to a category not in other Ships' configuration, those Ships will
+  Torrents to a category not in other Ships' cfguration, those Ships will
   ignore it and never sync nor show them in search results.
 ###
-module.exports = (nil, config) ->
-  # Category names must be lowercase, or they'll be ignored
-  config.set 'categories', {
-    anime: []
-    applications: []
-    books: []
-    code: []
-    documents: []
-    games: []
-    movies: []
-    music: []
-    images: []
-    porn: []
-    tv: []
-    others: []
+module.exports = (cfg) ->
+  # Category names must be lowercase, or they'll be ignored.
+  # If you remove any, remember users might try to upload
+  # wrongly-categorized content.
+  cfg.set 'categories', {
+    audio: [
+      'music'
+      'audio books'
+      'sound clips'
+    ]
+    applications: [
+      'windows'
+      'max'
+      'unix'
+      'ios'
+      'android'
+    ]
+    games: [
+      'pc'
+      'mac'
+      'psx'
+      'xbox 360'
+      'wii'
+      'handheld'
+      'ios'
+      'android'
+    ]
+    others: [
+      'e-books'
+      'comics'
+      'pictures'
+      'covers'
+      'physibles'
+      'documents'
+    ]
+    porn: [
+      'movies'
+      'dvds'
+      'pictures'
+      'games'
+      '3d'
+    ]
+    video: [
+      'movies'
+      'dvds'
+      'music'
+      'tv'
+      '3d'
+    ]
   }


client/billing: change subscription title logic

--- client/component-lab/SubscriptionHeader/SubscriptionHeader.coffee
+++ client/component-lab/SubscriptionHeader/SubscriptionHeader.coffee
@@ -48,9 +48,12 @@
         isDanger = daysLeft < 4
         "You have #{daysLeft} days left in your trial."

-      else
+      when endsAt and daysLeft
         billingDate = moment(Number @props.endsAt).format 'MMM Do, YYYY'
         "Your next billing date is #{billingDate}."
+
+      else
+        'Enter a credit card to re-activate subscription.'

     <Col xs={8}>
       <Label size="small" type={if isDanger then 'danger' else 'info'}>


Change value to true instead of 1

Change value to true instead of 1

--- packages/rocketchat-lib/server/models/Subscriptions.coffee
+++ packages/rocketchat-lib/server/models/Subscriptions.coffee
@@ -311,7 +311,7 @@

 		update =
 			$set:
-				blocked: 1
+				blocked: true

 		query2 =
 			rid: rid
@@ -319,7 +319,7 @@

 		update2 =
 			$set:
-				blocker: 1
+				blocker: true

 		return @update(query, update) and @update(query2, update2)


Updating cart item

Updating cart item

--- src/features/cart.coffee
+++ src/features/cart.coffee
@@ -26,7 +26,7 @@

 		Update: (id, data, callback, error) ->

-			return @m.Request 'carts/'+@identifier+'/items/'+id, 'PUT', data, callback, error
+			return @m.Request 'carts/'+@identifier+'/item/'+id, 'PUT', data, callback, error

 		Delete: (callback, error) ->

@@ -34,11 +34,11 @@

 		Remove: (id, callback, error) ->

-			return @m.Request 'carts/'+@identifier+'/items/'+id, 'DELETE', null, callback, error
+			return @m.Request 'carts/'+@identifier+'/item/'+id, 'DELETE', null, callback, error

 		Item: (id, callback, error) ->

-			return @m.Request 'carts/'+@identifier+'/items/'+id, 'GET', null, callback, error
+			return @m.Request 'carts/'+@identifier+'/item/'+id, 'GET', null, callback, error

 		InCart: (id, callback, error) ->


Set itemView height and width on position, and fix bug in add.

--- src/grid/GridView.coffee
+++ src/grid/GridView.coffee
@@ -5,6 +5,7 @@
 ###
 defaults      = require 'lodash/defaults'
 ComponentView = require '../component/ComponentView'
+isUndefined   = require 'lodash/isUndefined'
 Packer        = require '../packer/Packer'
 throttle      = require 'lodash/throttle'
 vars          = require '../vars'
@@ -50,6 +51,8 @@
       pos = shifted[item.id]
       item.row = pos.row
       item.column = pos.col
+      item.height = pos.height
+      item.width = pos.width
       if item.id not in skip
         [top, left] = @fromGridCoords pos.row, pos.col
         [height, width] = @fromGridCoords pos.height, pos.width
@@ -319,12 +322,13 @@
   _addItem: (itemView) ->
     {height, width, id} = itemView

-    if not itemView.row or not itemView.column
+    if isUndefined(itemView.row) or isUndefined(itemView.column)
       [row, col] = @_packer.insert height, width, id
       itemView.row = row
       itemView.column = col
     else
       {row, column} = itemView
+      col = column
       @_packer.insertAt height, width, row, column, id

     [top, left] = @fromGridCoords row, col


Automatically select the specimen label tool after marking the barcode

--- overrides.coffee
+++ overrides.coffee
@@ -76,6 +76,10 @@
       {label} = decisionTree.currentTask.getChoice() ? ''
       legend = tool.controls?.el.querySelector 'legend'
       legend.textContent = label if legend?
+
+      if page.decisionTree.currentTask.key is 'barcode'
+        task = page.decisionTree.currentTask
+        task.check task.choices[1]

     page.on page.LOAD_SUBJECT, (e, subject)->
       ms.rescale 0, 0, subjectViewer.maxWidth, subjectViewer.maxHeight


Remove path.resolve() call

Remove path.resolve() call

Fixes #7 and also enables the passing of an array to ```entry``` config property to support multiple entry files

--- tasks/browserify2.coffee
+++ tasks/browserify2.coffee
@@ -10,7 +10,7 @@
     config = grunt.config.get(@name)
     targetConfig = config[@target]
     {entry, mount, server, debug, compile, beforeHook} = targetConfig
-    bundle = browserify path.resolve(process.cwd(), entry)
+    bundle = browserify entry
     grunt.config.requires("#{@name}.#{@target}.entry")

     if beforeHook


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/controllable.coffee
+++ test/controllable.coffee
@@ -31,7 +31,7 @@
   ;

 test "should move player back and forth when keys are changed", ->
-
+  ;

 module()


Fixed compile error and bug introduced by recent change.

--- app/assets/javascripts/main.coffee
+++ app/assets/javascripts/main.coffee
@@ -221,7 +221,7 @@
     @route "", () ->
         # Load saved state of hide checkbox and attach event handler
         self = this
-        if window.localStorage.getItem('hideUnconfirmed') == true:
+        if window.localStorage.getItem('hideUnconfirmed') == "true"
             $("#hideUnconfirmed").prop("checked", true)
         $("#hideUnconfirmed").change(() ->
     	    window.localStorage.setItem('hideUnconfirmed', $("#hideUnconfirmed").prop("checked"))


Build: installing/building/exporting landing page

--- build-client.coffee
+++ build-client.coffee
@@ -18,6 +18,7 @@
 Promise           = require 'bluebird'
 which             = Promise.promisify require 'which'
 buildAPI          = require 'bongo-api-builder'
+bongo             = require 'bongo'

 args =
@@ -87,30 +88,60 @@
       spriteHelper = helper
       @buildClient options

-  buildFramework:->
-
-    uglify = unless process.env.NO_UGLIFYJS then "--uglify" else ""
-
-    buildLoggedInFramework  = "cd client/Framework && npm i && gulp compile #{uglify} --outputDir=../../website/a/"
-    buildLoggedOutFramework = "cd client/Framework && npm i && gulp compile #{uglify} --outputDir=../../website/a/out/  --entryPath=../entry.coffee"
-    exec buildLoggedInFramework, (err, stdout, stderr)->
-      console.log """
-      ----------------------------------- KD FRAMEWORK COMPILED -----------------------------------
-       To use watcher for Framework use following command in different tab:
-       $ #{buildLoggedInFramework.replace 'compile ', ''}
-      ---------------------------------------------------------------------------------------------
-      """
-
-      # exec buildLoggedOutFramework, (err, stdout, stderr)->
-      #   console.log """
-      #   ----------------------------- KD FRAMEWORK LOGGEDOUT COMPILED -------------------------------
-      #   """
+  buildExternals:->
+
+    {daisy} = bongo
+
+    queue = [
+      ->
+        console.log "\n# EXTERNAL BUILDS STARTED\n"
+        uglify = unless process.env.NO_UGLIFYJS then "--uglify" else ""
+        buildLoggedInFramework = "cd client/Framework && npm i && gulp compile #{uglify} --outputDir=../../website/a/"
+        exec buildLoggedInFramework, (err, stdout, stderr)->
+          if err
+          then console.error err
+          else console.log """
+          # KD FRAMEWORK COMPILED
+           To use watcher for Framework use following command in different tab:
+           $ #{buildLoggedInFramework.replace 'compile ', ''}
+          """
+          queue.next()
+      ,
+      ->
+        exec 'cd client/landing && npm i', (err, stdout, stderr)->
+          if err
+          then console.error err
+          else console.log "# LANDING PAGE DEPENDENCIES INSTALLED"
+          queue.next()
+      ,
+      ->
+        exec 'cd client/landing && gulp build', (err, stdout, stderr)->
+          if err
+          then console.error err
+          else console.log """
+          # LANDING PAGE BUILT
+           For further development of landing page, clone koding/landing and follow its readme.
+          """
+          queue.next()
+      ,
+      ->
+        exec "cp -Rf #{__dirname}/client/landing/static/out #{__dirname}/website/a/out", (err, stdout, stderr)->
+          if err
+          then console.error err
+          else console.log "# LANDING PAGE EXPORTED"
+          queue.next()
+      ->
+          console.log "\n# EXTERNAL BUILDS FINISHED!\n"
+          queue.next()
+    ]
+
+    daisy queue, ->

   buildClient: (options) ->

     try fs.mkdirSync ".build"

-    @buildFramework()
+    @buildExternals()

     buildAPI
       rootDir   : __dirname


Add WRBB4 file I/O support

Add WRBB4 file I/O support

--- src/board/wakayamarbboard.coffee
+++ src/board/wakayamarbboard.coffee
@@ -90,6 +90,9 @@
     0x21290531  # Tokuden driver
     0x045b0234  # Renesas driver
   ]
+
+  @POLL_BY_FEH: 100   # Enable polling by 0xfe at 100ms intervals
+  @BINARY_MODE: true

   TOL5V = new I18n({en: "5V tolerant", ja: "5Vトレラント"})
   ADPIN = new I18n({en: "With analog input", ja: "アナログ入力対応"})
@@ -336,8 +339,8 @@
   @private
   @method
     Receive data
-  @param {string/ArrayBuffer} expect
-    Wait data
+  @param {string/ArrayBuffer/number} expect
+    Wait data or number of bytes
   @return {Promise}
     Promise object
   @return {ArrayBuffer} return.PromiseValue
@@ -355,9 +358,12 @@
       App.log.verbose("WakayamaRbBoard#_wait(%o)", expect)
       return str2ab(expect) if typeof(expect) == "string"
       return expect
-    ).then((ab) =>
+    ).then((ab_len) =>
+      token = new Uint8Array(ab_len) if ab_len instanceof ArrayBuffer
+      length = ab_len if typeof(ab_len) == "number"
       return new Promise((resolve, reject) =>
-        @_waiter = {token: new Uint8Array(ab), resolve: resolve, reject: reject}
+        @_waiter = {token: token, length: length, resolve: resolve, reject: reject}
+        @_receiveHandler(null)
       )
     ) # return Promise.resolve().then()...

@@ -394,13 +400,21 @@
     Received data
   ###
   _receiveHandler: (ab) ->
-    return unless ab.byteLength > 0
-    do (ab) ->
-      pro = null
-      Object.defineProperty(ab, "ab2str", get: -> pro or= ab2str(ab))
-      App.log.verbose("WakayamaRbBoard#_recv(%o, %i bytes)", ab, ab.byteLength)
-    @_recvBuffer or= new FifoBuffer()
-    @_recvBuffer.push(ab)
+    if ab?.byteLength > 0
+      do (ab) ->
+        pro = null
+        Object.defineProperty(ab, "ab2str", get: -> pro or= ab2str(ab))
+        App.log.verbose("WakayamaRbBoard#_recv(%o, %i bytes)", ab, ab.byteLength)
+      @_recvBuffer or= new FifoBuffer()
+      @_recvBuffer.push(ab)
+    tlen = @_waiter?.length
+    if tlen?
+      return if tlen < @_recvBuffer.byteLength
+      data = @_recvBuffer.shift(tlen)
+      resolve = @_waiter.resolve
+      @_waiter = null
+      resolve?(data)
+      return
     token = @_waiter?.token
     return unless token?
     tlen = token.byteLength
@@ -456,6 +470,7 @@
       ).then(=>
         return @_wrbb._lock(lock)
       ).then(=>
+        return @_wrbb._send("G #{@_dir}#{path}\r") if @_binaryMode
         return @_wrbb._send("F #{@_dir}#{path}\r")
       ).then(=>
         return @_wrbb._wait("\r\nWaiting").timeout(CMD_TIMEOUT_MS)
@@ -470,15 +485,19 @@
         )
         return @_wrbb._send("\r")
       ).then(=>
+        return @_wrbb._wait(result.byteLength) if @_binaryMode
         return @_wrbb._wait("\r\n").timeout(CMD_TIMEOUT_MS)
       ).then(=>
         return @_wrbb._wait("\r\n").timeout(READ1K_TIMEOUT_MS * ((length + 1024) / 1024))
       ).then((readdata) =>
         src = new Uint8Array(readdata)
-        for i in [0...result.byteLength] by 1
-          byte = (HEX2BIN[src[i*2+0]] << 4) + (HEX2BIN[src[i*2+1]])
-          return Promise.reject("Receive data error at byte ##{i}") if isNaN(byte)
-          result[i] = byte
+        if @_binaryMode
+          result.set(src)
+        else
+          for i in [0...result.byteLength] by 1
+            byte = (HEX2BIN[src[i*2+0]] << 4) + (HEX2BIN[src[i*2+1]])
+            return Promise.reject("Receive data error at byte ##{i}") if isNaN(byte)
+            result[i] = byte
         return result.buffer unless options.encoding?   # Last PromiseValue (ArrayBuffer)
         return ab2str(result.buffer, options.encoding)  # Last PromiseValue (string)
       ).finally(=>
@@ -499,16 +518,20 @@
         return str2ab(data, options.encoding)
       ).then((buffer) =>
         src = new Uint8Array(buffer)
+        return @_wrbb._send("W #{@_dir}#{path} #{src.byteLength}\r") if @_binaryMode
         return @_wrbb._send("U #{@_dir}#{path} #{src.byteLength * 2}\r")
       ).then(=>
         return @_wrbb._wait("\r\nWaiting").timeout(CMD_TIMEOUT_MS)
       ).then(=>
-        dump = ""
-        for i in [0...src.byteLength] by 1
-          dump += BIN2HEX[src[i]]
+        if @_binaryMode
+          dump = data
+        else
+          dump = ""
+          for i in [0...src.byteLength] by 1
+            dump += BIN2HEX[src[i]]
         return @_wrbb._send(dump)
       ).then(=>
-        return @_wrbb._wait("Saving").timeout(CMD_TIMEOUT_MS)
+        return @_wrbb._wait("Saving").timeout(WRITE1K_TIMEOUT_MS * ((src.byteLength + 1024) / 1024))
       ).then(=>
         return @_wrbb._pull(
           @_wrbb._wait("\r\n>")
@@ -556,6 +579,7 @@
       Base directory
     ###
     constructor: (@_wrbb, @_dir = "") ->
+      @_binaryMode = @_wrbb.constructor.BINARY_MODE
       super(AsyncFs.BOARD_INTERNAL)
       return


User able to select which fields to plot

--- app/controllers/Scatterplot.coffee
+++ app/controllers/Scatterplot.coffee
@@ -4,6 +4,7 @@
 class Scatterplot extends BaseController
   constructor: ->
     super
+
     @xAxisKey = 'ra'
     @yAxisKey = 'dec'
     @createGraph()
@@ -31,8 +32,32 @@
     require('views/scatterplot_tooltip')({datum, xAxis, yAxis})

   start: =>
+    @addData()
+    @addFieldsToAxes()
     @addAxis()
-    @addData()
+
+  addFieldsToAxes: ->
+    attrs = @data[0].constructor.attributes
+    options = ""
+    for attr in attrs
+      options += "<option value='#{attr}'>#{attr}</option>"
+
+    $("##{@channel}").append("
+      <select class='x-axis'>
+        #{options}
+      </select>
+      <select class='y-axis'>
+        #{options}
+      </select>
+    ")
+
+    $("##{@channel} .x-axis").change (e) =>
+      @xAxisKey = e.currentTarget.value
+      @addData()
+
+    $("##{@channel} .y-axis").change (e) =>
+      @yAxisKey = e.currentTarget.value
+      @addData()

   addData: (options) ->
     options =


ComboBox: addItemAt deprecated use addChildAt.

--- src/lib/components/combobox/ComboBox.coffee
+++ src/lib/components/combobox/ComboBox.coffee
@@ -134,7 +134,7 @@
     return unless item instanceof goog.ui.MenuItem

     if index?
-      @menu_.addItemAt item, index
+      @menu_.addChildAt item, index, yes
     else
       @menu_.addItem item


fixing selections on fastpath

fixing selections on fastpath

--- subtree/bokehjs/static/coffee/renderers/glyph/circle.coffee
+++ subtree/bokehjs/static/coffee/renderers/glyph/circle.coffee
@@ -68,8 +68,8 @@
           props =  @selection_glyphprops
         else
           props = @glyph_props
-        @_fast_path(ctx, props, 'selected')
-        @_fast_path(ctx, @nonselection_glyphprops, 'unselected')
+        @_fast_path(ctx, props, true)
+        @_fast_path(ctx, @nonselection_glyphprops, false)
       else
         @_fast_path(ctx)
     else
@@ -88,7 +88,7 @@
     if not glyph_props
       glyph_props = @glyph_props
     if glyph_props.fill_properties.do_fill
-      @glyph_props.fill_properties.set(ctx, @glyph_props)
+      glyph_props.fill_properties.set(ctx, @glyph_props)
       ctx.beginPath()
       for i in [0..@sx.length-1]
         if isNaN(@sx[i] + @sy[i] + @radius[i]) or not @mask[i]
@@ -102,7 +102,7 @@
       ctx.fill()

     if glyph_props.line_properties.do_stroke
-      @glyph_props.line_properties.set(ctx, @glyph_props)
+      glyph_props.line_properties.set(ctx, @glyph_props)
       ctx.beginPath()
       for i in [0..@sx.length-1]
         if isNaN(@sx[i] + @sy[i] + @radius[i]) or not @mask[i]


Hooked up real-time playback music.

Hooked up real-time playback music.

--- app/lib/surface/MusicPlayer.coffee
+++ app/lib/surface/MusicPlayer.coffee
@@ -12,6 +12,8 @@
   subscriptions:
     'music-player:play-music': 'onPlayMusic'
     'audio-player:loaded': 'onAudioLoaded'
+    'playback:real-time-playback-started': 'onRealTimePlaybackStarted'
+    'playback:real-time-playback-ended': 'onRealTimePlaybackEnded'

   constructor: ->
     super arguments...
@@ -62,6 +64,17 @@
     createjs.Tween.removeTweens(@currentMusic)
     @currentMusic.volume = if me.get('music') then MUSIC_VOLUME else 0.0

+  onRealTimePlaybackStarted: (e) ->
+    @previousMusic = @currentMusic
+    trackNumber = _.random 0, 2
+    Backbone.Mediator.publish 'music-player:play-music', file: "/music/music_real_time_#{trackNumber}", play: true
+
+  onRealTimePlaybackEnded: (e) ->
+    @fadeOutCurrentMusic()
+    if @previousMusic
+      @currentMusic = @previousMusic
+      @restartCurrentMusic()
+
   destroy: ->
     me.off 'change:music', @onMusicSettingChanged, @
     super()


add upload whitelist checkbox admin field

allow admins to whitelist users to skip upload checks, add autosave to this component but keep the other admin fields disabled.

--- app/pages/admin/user-settings.cjsx
+++ app/pages/admin/user-settings.cjsx
@@ -24,6 +24,7 @@

Admin: <UserCheckboxToggle editUser={@props.editUser} field="admin" disabled />

Login prompt: <UserCheckboxToggle editUser={@props.editUser} field="login_prompt" disabled />

Private profile: <UserCheckboxToggle editUser={@props.editUser} field="private_profile" disabled />

+
Whitelist subject uploads: <UserCheckboxToggle editUser={@props.editUser} field="upload_whitelist" />

Uploaded subjects: { @props.editUser.uploaded_subjects_count }

<UserLimitToggle editUser={@props.editUser} />

@@ -49,9 +50,14 @@
   render: ->
     editUser = @props.editUser
     setting = editUser[@props.field]
-
-      <input type="checkbox" disabled={@props.disabled} name={@props.field} value={setting} checked={setting} onChange={@set.bind this, @props.field, not setting} />
-
+    console.log setting
+

+      <AutoSave resource={editUser}>
+
+          <input type="checkbox" disabled={@props.disabled} name={@props.field} value={setting} checked={setting} onChange={handleInputChange.bind editUser} />
+
+      </AutoSave>
+

 UserLimitToggle = React.createClass
   displayName: "User limit toggle"


Fix app/spectrogram example (#7231)

Fix app/spectrogram example (#7231)

* Fix app/spectrogram example

* compute height correctly and encapsulate image update

--- examples/app/spectrogram/waterfall.coffee
+++ examples/app/spectrogram/waterfall.coffee
@@ -32,41 +32,23 @@
   render: () ->
     ctx = @plot_view.canvas_view.ctx

-    for i in [0...@x.length]
-      @x[i] += 1
-
-    @col -= 1
-    if @col < 0
-      @col = @model.tile_width - 1
-      @tile -= 1
-      if @tile < 0
-        @tile = @x.length - 1
-      @x[@tile] = -@model.tile_width
-
-    buf32 = new Uint32Array(@cmap.v_map_screen(@model.latest))
-    for i in [0...@model.gram_length]
-      @image[@tile][i*@model.tile_width+@col] = buf32[i]
-
-    sx = @xscale.v_compute(x)
-    sy = @yscale.compute(0)
-    sw = Math.ceil(@xscale.compute(@model.tile_width) - @xscale.compute(0))
-    sh = Math.ceil(@yscale.compute(@max_freq))
-
     ctx.save()

     smoothing = ctx.getImageSmoothingEnabled()
     ctx.setImageSmoothingEnabled(false)
+
+    @_update_tiles()
+
+    sx = @xscale.v_compute(@x)
+    sy = @yscale.compute(0)
+    sw = Math.ceil(@xscale.compute(@model.tile_width) - @xscale.compute(0))
+    sh = Math.ceil(@yscale.compute(0) - @yscale.compute(@max_freq))

     ctx.translate(0, sy)
     ctx.scale(1, -1)
     ctx.translate(0, -sy)

     for i in [0...sx.length]
-      if i == @tile
-        cctx = @canvas[i].getContext('2d')
-        image = cctx.getImageData(0, 0, @model.tile_width, @model.gram_length)
-        image.data.set(new Uint8Array(@image[i].buffer))
-        cctx.putImageData(image, 0, 0)
       ctx.drawImage(@canvas[i], sx[i], sy, sw, sh)

     ctx.translate(0, sy)
@@ -76,6 +58,32 @@
     ctx.setImageSmoothingEnabled(smoothing)

     ctx.restore()
+
+  _update_tiles: () ->
+    # shift all tiles to the right by one
+    for i in [0...@x.length]
+      @x[i] += 1
+
+    # if we've updated the last column in the current tile, move to the next tile
+    # in the buffer (rotating the buffer if necessary)
+    @col -= 1
+    if @col < 0
+      @col = @model.tile_width - 1
+      @tile -= 1
+      if @tile < 0
+        @tile = @x.length - 1
+      @x[@tile] = -@model.tile_width
+
+    # apply the lastest column to the current tile image
+    buf32 = new Uint32Array(@cmap.v_map_screen(@model.latest))
+    for i in [0...@model.gram_length]
+      @image[@tile][i*@model.tile_width+@col] = buf32[i]
+
+    # update the tiles canvas with the image data
+    cctx = @canvas[@tile].getContext('2d')
+    image = cctx.getImageData(0, 0, @model.tile_width, @model.gram_length)
+    image.data.set(new Uint8Array(@image[@tile].buffer))
+    cctx.putImageData(image, 0, 0)

 export class WaterfallRenderer extends Renderer
   type: 'WaterfallRenderer'


Add "space" keybinding which uses the "move-right" motion

--- keymaps/vim-mode.cson
+++ keymaps/vim-mode.cson
@@ -8,6 +8,7 @@
   'left': 'vim-mode:move-left'
   'backspace': 'core:move-left'
   'l': 'vim-mode:move-right'
+  'space': 'vim-mode:move-right'
   'right': 'vim-mode:move-right'
   'k': 'vim-mode:move-up'
   'up': 'vim-mode:move-up'


Deprecate App.require methods.

Deprecate App.require methods.

--- src/app.coffee
+++ src/app.coffee
@@ -35,7 +35,10 @@
   # your app where to look for coffeescript source files. This
   # implementation may change in the future.
   Batman.developer.do =>
+    requireDeprecated = "Please use whatever means you'd like to load your code before calling App.run."
+
     App.require = (path, names...) ->
+      Batman.deprecated("App.require", requireDeprecated)
       base = @requirePath + path
       for name in names
         @prevent 'run'
@@ -54,13 +57,16 @@
       @

     @controller = (names...) ->
+      Batman.deprecated("App.controller", requireDeprecated)
       names = names.map (n) -> n + '_controller'
       @require 'controllers', names...

     @model = ->
+      Batman.deprecated("App.model", requireDeprecated)
       @require 'models', arguments...

     @view = ->
+      Batman.deprecated("App.view", requireDeprecated)
       @require 'views', arguments...

   # Layout is the base view that other views can be yielded into. The


Create dummy-unit if default feedback-form is triggered

--- src/app.coffee
+++ src/app.coffee
@@ -65,6 +65,10 @@
     # (leaflet.activearea overrides getBounds)
     L.Map.prototype._originalGetBounds = L.Map.prototype.getBounds

+    # TODO:
+    window.DEFAULT_FEEDBACK_UNIT = 10000
+
+
     DEBUG_STATE = appSettings.debug_state
     VERIFY_INVARIANTS = appSettings.verify_invariants

@@ -263,7 +267,7 @@
             sm.resolveImmediately()

         composeFeedback: (unit) ->
-            app.getRegion('feedbackFormContainer').show new FeedbackFormView model: @pendingFeedback, unit: unit
+            app.getRegion('feedbackFormContainer').show new FeedbackFormView model: @pendingFeedback, unit: unit || new Models.Unit id: DEFAULT_FEEDBACK_UNIT
             $('#feedback-form-container').on 'shown.bs.modal', ->
                 $(@).children().attr('tabindex', -1).focus()
             $('#feedback-form-container').modal('show')


app: use observables for updating req/res, fixes #17

--- src/app.coffee
+++ src/app.coffee
@@ -35,28 +35,28 @@
   constructor: ({requests}) ->
     router = new Routes()

-    $homePage = new HomePage()
-    $redPage = new RedPage()
-    $fourOhFourPage = new FourOhFourPage()
+    requests = requests.map ({req, res}) ->
+      route = router.match req.path
+      $page = route.fn()
+
+      return {req, res, route, $page}
+
+    $homePage = new HomePage({
+      requests: requests.filter ({$page}) -> $page instanceof HomePage
+    })
+    $redPage = new RedPage({
+      requests: requests.filter ({$page}) -> $page instanceof RedPage
+    })
+    $fourOhFourPage = new FourOhFourPage({
+      requests: requests.filter ({$page}) -> $page instanceof FourOhFourPage
+    })

     router.addRoute '/', -> $homePage
     router.addRoute '/red', -> $redPage
     router.addRoute '*', -> $fourOhFourPage

-    @state = z.state {
-      requests: requests
-      $currentPage: null
-      $nextPage: null
-      isEntering: false
-      isActive: false
-    }
-
-    # FIXME: should not need subscribe
-    requests.subscribe ({req, res}) =>
+    handleRequest = requests.doOnNext ({req, res, route, $page}) =>
       {$currentPage} = @state.getValue()
-
-      route = router.match req.path
-      $page = route.fn()

       if $page instanceof FourOhFourPage
         res.status? 404
@@ -85,11 +85,19 @@
         @state.set
           $currentPage: $page

+    @state = z.state {
+      handleRequest: handleRequest
+      $currentPage: null
+      $nextPage: null
+      isEntering: false
+      isActive: false
+    }
+
   render: =>
     {$nextPage, $currentPage, isEntering, isActive} = @state.getValue()

     z 'html',
-      $currentPage.renderHead {styles, bundlePath}
+      $currentPage?.renderHead {styles, bundlePath}
       z 'body',
         z '#zorium-root',
           z '.z-root',


Change IP address update interval from 5m to 30s

--- src/app.coffee
+++ src/app.coffee
@@ -89,7 +89,7 @@
 				ip_address: ipAddrs.join(' ')
 			)
 	console.log('Starting periodic check for IP addresses..')
-	setInterval(updateIpAddr, 5 * 60 * 1000) # Every 5 mins
+	setInterval(updateIpAddr, 30 * 1000) # Every 30s
 	updateIpAddr()

 	console.log('Starting connectivity check..')


Add missing modal show call.

Add missing modal show call.

--- src/app.coffee
+++ src/app.coffee
@@ -301,6 +301,7 @@

         showAccessibilityStampDescription: ->
             app.getRegion('feedbackFormContainer').show new disclaimers.ServiceMapAccessibilityDescriptionView()
+            $('#feedback-form-container').modal('show')

         showExportingView: ->
             app.getRegion('feedbackFormContainer').show new ExportingView appModels


added throttling support to the API (security, still and again :( )

--- src/app.coffee
+++ src/app.coffee
@@ -59,6 +59,17 @@
 Server.use Restify.dateParser()
 Server.use Restify.queryParser()
 Server.use Restify.urlEncodedBodyParser()
+Server.use Restify.throttle {
+  burst: 100,
+  rate: 50,
+  ip: true,
+  #overrides: {
+  #  '192.168.1.1': {
+  #    rate: 0,#unlimited
+  #    burst: 0
+  #  }
+  #}
+}
 Server.use Sanitize.sanitize {
     'groupname': /^[a-zA-Z-_0-9]+$/i
     'mapname': /^[a-zA-Z-_0-9]+$/i
@@ -71,7 +82,6 @@
   * return main file
   * return main file on right start page ?
   * config file
-  * throttle
   * version API
   * doc
   * tests


Fix parsing of curl comands with multiple spaces


Tweak #2007.

Tweak #2007.

--- background_scripts/bg_utils.coffee
+++ background_scripts/bg_utils.coffee
@@ -18,12 +18,10 @@
       @deregister removedTabId
       @register addedTabId

-    self = @
-    chrome.windows.onFocusChanged.addListener (wnd) ->
-      return if wnd == chrome.windows.WINDOW_ID_NONE
-      chrome.tabs.query {windowId: wnd, active: true}, (tabs) ->
-        self.register tabs[0].id if tabs[0]
-        chrome.runtime.lastError
+    chrome.windows.onFocusChanged.addListener (wnd) =>
+      if wnd != chrome.windows.WINDOW_ID_NONE
+        chrome.tabs.query {windowId: wnd, active: true}, (tabs) =>
+          @register tabs[0].id if tabs[0]

   register: (tabId) ->
     currentTime = new Date()


Remove references to enterNormalMode command.

--- background_scripts/commands.coffee
+++ background_scripts/commands.coffee
@@ -166,7 +166,6 @@
       "enterVisualMode",
       "enterVisualLineMode",
       "passNextKey",
-      "enterNormalMode",
       "focusInput",
       "LinkHints.activateMode",
       "LinkHints.activateModeToOpenInNewTab",
@@ -239,7 +238,6 @@
     "closeOtherTabs",
     "enterVisualLineMode",
     "toggleViewSource",
-    "enterNormalMode",
     "passNextKey"]

 defaultKeyMappings =
@@ -356,7 +354,6 @@
   passNextKey: ["Pass the next key to Chrome"]
   enterVisualMode: ["Enter visual mode", { noRepeat: true }]
   enterVisualLineMode: ["Enter visual line mode", { noRepeat: true }]
-  enterNormalMode: ["Handle following key sequence in normal mode"]

   focusInput: ["Focus the first text input on the page"]


fix calculation for right+bottom margins

--- pie_chart.coffee
+++ pie_chart.coffee
@@ -4,9 +4,9 @@
     # Margins: zero if not set or the same as the opposite margin
     # (you likely want this to keep the chart centered within the widget)
     left = @get('leftMargin') || 0
-    right = if @get('rightMargin')? then @get('rightMargin') else left
+    right = @get('rightMargin') || left
     top = @get('topMargin') || 0
-    bottom = if @get('bottomMargin')? then @get('bottomMargin') else top
+    bottom = @get('bottomMargin') || top

     container = $(@node).parent()
     # Gross hacks. Let's fix this.


test fix

test fix

--- spec/atom-clock-package-spec.coffee
+++ spec/atom-clock-package-spec.coffee
@@ -1,5 +1,5 @@
 describe 'Atom Clock package', ->
-
+
   [workspaceElement, activationPromise, statusBarPromise] = []

   beforeEach ->
@@ -10,7 +10,6 @@
   describe 'when the package is activated', ->

     it 'should show the clock', ->
-      expect(workspaceElement.querySelector('.atom-clock')).not.toExist()

       waitsForPromise ->
         statusBarPromise


cli example

cli example

--- src/cli.coffee
+++ src/cli.coffee
@@ -19,7 +19,7 @@
       Usage examples:

         $ authrc create --path /home/user/
-        $ authrc add --path ./.authrc
+        $ authrc add
         $ authrc remove my.host.org
         $ authrc update my.host.org
         $ authrc decrypt e9b90003128c4215ba005a08615fa64f


Explain the odd return value from CLI.help()

--- src/cli.coffee
+++ src/cli.coffee
@@ -52,7 +52,9 @@

 CLI.help = (command, description) ->
   _help.command(command).description(description)
-  CLI
+
+  # Prevent access to the command instance returned by Commander
+  true

 CLI.command = (name, description, fn) ->


- removed imports section - fixed iteration generation

--- src/code/crystal/generate.coffee
+++ src/code/crystal/generate.coffee
@@ -21,77 +21,6 @@

 loaded_modules = {}

-loadImports = (imports) ->
-	loaded_imports = {}
-
-	# check if each import exists
-	for import_id of imports
-		#console.log "- #{import_id}"
-
-		# get import module
-		import_alias = imports[import_id]
-		import_parts = import_id.split '.'
-		module_name = import_parts[0]
-		import_name = import_parts[1]
-
-		# module is not loaded
-		if !modules[module_name]
-			throw new Error "Module (#{module_name}.#{import_name}) not initialized for import (#{import_parts[2]})"
-
-		# get import module
-		import_module = modules[module_name]
-		module_id = import_module.id
-		import_config = import_module.config
-		import_path = import_module.path
-
-		# load exported
-		exported = import_config.exports[import_name]
-		if !exported
-			error = "Export (#{import_name}) does not exist for import (#{module_id}).\nTry these instead:"
-			for module_export of import_config.exports
-				error += "\n- #{module_export}"
-			throw new Error error
-
-		# load child imports
-		if import_config.imports
-			console.log "Loading modules for #{module_id}..."
-			child_modules = loadModules import_config.modules
-			console.log "Loading imports for #{import_name}..."
-			child_imports = loadImports import_config.imports, child_modules
-
-		loaded_imports[import_alias] = exported
-		loaded_imports[import_alias].imports = child_imports
-
-		if !exported.type
-			throw new Error "Type is required for export (#{import_name}) in module (#{module_id})"
-
-		switch exported.type
-			when 'configuration'
-				loaded_imports[import_alias].config = exported.config
-				loaded_imports[import_alias].doc = fs.readFileSync "#{import_path}/.crystal/config.yml"
-			when 'engine'
-				loaded_imports[import_alias].engine = require "#{import_path}/.crystal/engine/#{exported.engine}"
-			when 'generator'
-				if exported.engine
-					loaded_imports[import_alias].engine = child_imports[exported.engine].engine
-				if exported.schema && typeof(exported.schema) == 'string'
-					loaded_imports[import_alias].schema = yaml.safeLoad fs.readFileSync("#{import_path}/.crystal/schema/#{exported.schema}")
-				if exported.template
-					loaded_imports[import_alias].template = fs.readFileSync "#{import_path}/.crystal/template/#{exported.template}", 'utf8'
-				if exported.transformer
-					loaded_imports[import_alias].transformer = child_imports[exported.transformer].transformer
-			when 'helper'
-				loaded_imports[import_alias].helper = require "#{import_path}/.crystal/helper/#{exported.helper}"
-			when 'processor'
-				loaded_imports[import_alias].processor = require "#{import_path}/.crystal/proc/#{exported.processor}"
-			when 'transformer'
-				loaded_imports[import_alias].transformer = require "#{import_path}/.crystal/trans/#{exported.transformer}"
-			when 'schematic'
-				loaded_imports[import_alias].schema = yaml.safeLoad fs.readFileSync("#{import_path}/.crystal/schema/#{exported.schema}")
-			else throw new Error "unknown type (#{exported.type}) for export (#{import_name}) in import (#{module_id})"
-
-	loaded_imports
-
 loadModules = (modules) ->
 	# load each module
 	for module_id of modules
@@ -180,6 +109,7 @@
 					test = loaded_module.imports[exported.helper].split('.')
 					test2 = test.pop()
 					test = test.join('.')
+
 					loaded_modules[module_name][version_name].exports[export_name].helper = {
 						callback: loaded_modules[test][loaded_module.modules[test]].exports[test2].helper
 						name: loaded_modules[test][loaded_module.modules[test]].exports[test2].name
@@ -206,85 +136,117 @@

 		# validate filename
 		if output.filename
-			filename = output.filename
+			generator_filename = output.filename
 		else if generator.filename
-			filename = generator.filename
+			generator_filename = generator.filename
 		else
 			throw new Error "Filename is required for output."

-		# append path to filename
-		if output.path
-			if !fs.existsSync output.path
-				mkdirp output.path
-			filename = "#{output.path}/#{filename}"
-
-		# validate spec
-		if !output.spec
-			throw new Error "Spec is required."
-
-		# load spec from file
-		if typeof(output.spec) == 'string'
-			output.spec = yaml.safeLoad fs.readFileSync(".crystal/spec/#{output.spec}", 'utf8')
-		output.spec = parse output.spec, project
-
-		# validate spec
-		if generator.schema
-			validate = skeemas.validate output.spec, generator.schema
-			if !validate.valid
-				console.log validate.errors
-				console.log("ERROR: Specification failed validation.")
-				for error in validate.errors
-					console.log "- #{error.message} for specification (#{error.context.substr(2)})"
-				throw new Error "ERROR: Invalid specification."
-
-		# get content from output
+		# get iterator
+		if generator.iterator
+			files = []
+			for name in output.spec[generator.iterator]
+				files.push name
+		else
+			# load spec from file
+			if typeof(output.spec) == 'string'
+				output.spec = yaml.safeLoad fs.readFileSync(".crystal/spec/#{output.spec}", 'utf8')
+			output.spec = parse output.spec, project
+
+			# validate spec
+			if generator.schema
+				validate = skeemas.validate output.spec, generator.schema
+				if !validate.valid
+					console.log validate.errors
+					console.log("ERROR: Specification failed validation.")
+					for error in validate.errors
+						console.log "- #{error.message} for specification (#{error.context.substr(2)})"
+					throw new Error "ERROR: Invalid specification."
+
+			files = [generator_filename]
+
+		# get engine
+		if output.engine
+			engine = output.engine
+		else if generator.engine
+			engine = generator.engine
+		else
+			engine = null
+
 		if generator.helper
 			helpers = [generator.helper]
 		else
 			helpers = null
-		content = generator.engine output.spec, generator.template, helpers
-
-		# transform content
-		if output.transformer
-			if typeof(output.transformer) == 'string'
-				content = imports[output.transformer].transformer content
+
+		for i of files
+			file = files[i]
+
+			# pass filename thru engine
+			if engine
+				filename = engine { name: file.name }, generator_filename, helpers
+
+			# append path to filename
+			if output.path
+				if !fs.existsSync output.path
+					mkdirp output.path
+				filename = "#{output.path}/#{filename}"
+
+			# validate spec
+			if !output.spec
+				throw new Error "Spec is required."
+
+			# get content from output
+			if engine
+				if generator.iterator
+					content = engine output.spec[generator.iterator][i], generator.template, helpers
+				else
+					content = engine output.spec, generator.template, helpers
+			else if generator.template
+				content = generator.template
 			else
-				content = output.transformer content
-		if generator.transformer
-			content = generator.transformer content
-
-			# get file/cache/ checksum
-		filename_checksum = crypto.createHash('md5').update(filename, 'utf8').digest('hex')
-		if fs.existsSync ".crystal/cache/#{filename_checksum}"
-			if !fs.existsSync filename
-				if force != true
-					throw new Error "ERROR: File (#{filename}) has been manually deleted outside of Crystal. Use -f to force code generation and overwrite this deletion."
-			else
-				cache_checksum = fs.readFileSync(".crystal/cache/#{filename_checksum}", 'utf8')
-				file_checksum = crypto.createHash('md5').update(fs.readFileSync(filename, 'utf8'), 'utf8').digest('hex')
-
-				# validate checksum
-				if cache_checksum != file_checksum && force != true
-					throw new Error "ERROR: File (#{filename}) has been manually changed outside of Crystal. Use -f to force code generation and overwrite these changes."
-
-		# get content checksum
-		content_checksum = crypto.createHash('md5').update(content, 'utf8').digest('hex')
-
-		# cache checksum
-		if !fs.existsSync ".crystal/cache"
-			mkdirp.sync ".crystal/cache"
-		fs.writeFileSync ".crystal/cache/#{filename_checksum}", content_checksum
-
-		# write content to file
-		file_last_path = filename.lastIndexOf('/')
-		if file_last_path != -1
-			mkdirp.sync filename.substr(0, file_last_path)
-		fs.writeFileSync filename, content
-
-		#console.log "- #{filename}"
-
-		#if generator.outputs
-			#loadOutputs generator.outputs, generator.imports, project, force
+				content = output.spec
+
+			# transform content
+			if output.transformer
+				if typeof(output.transformer) == 'string'
+					content = imports[output.transformer].transformer content
+				else
+					content = output.transformer content
+			if generator.transformer
+				content = generator.transformer content
+
+				# get file/cache/ checksum
+			filename_checksum = crypto.createHash('md5').update(filename, 'utf8').digest('hex')
+			if fs.existsSync ".crystal/cache/#{filename_checksum}"
+				if !fs.existsSync filename
+					if force != true
+						throw new Error "ERROR: File (#{filename}) has been manually deleted outside of Crystal. Use -f to force code generation and overwrite this deletion."
+				else
+					cache_checksum = fs.readFileSync(".crystal/cache/#{filename_checksum}", 'utf8')
+					file_checksum = crypto.createHash('md5').update(fs.readFileSync(filename, 'utf8'), 'utf8').digest('hex')
+
+					# validate checksum
+					if cache_checksum != file_checksum && force != true
+						throw new Error "ERROR: File (#{filename}) has been manually changed outside of Crystal. Use -f to force code generation and overwrite these changes."
+
+			# get content checksum
+			content_checksum = crypto.createHash('md5').update(content, 'utf8').digest('hex')
+
+			# cache checksum
+			if !fs.existsSync ".crystal/cache"
+				mkdirp.sync ".crystal/cache"
+			fs.writeFileSync ".crystal/cache/#{filename_checksum}", content_checksum
+
+			# write content to file
+			file_last_path = filename.lastIndexOf('/')
+			if file_last_path != -1
+				mkdirp.sync filename.substr(0, file_last_path)
+			fs.writeFileSync filename, content
+
+			console.log "- #{filename}"
+
+			#if generator.outputs
+				#loadOutputs generator.outputs, generator.imports, project, force

 generate = (project) ->
 	console.log "Generating code from: #{this.path}"


Fix relationship symbols no longer come up [#136989689]

--- src/code/views/graph-view.coffee
+++ src/code/views/graph-view.coffee
@@ -120,6 +120,7 @@
     if (prevState.description.links != @state.description.links) or
         (prevState.simulationPanelExpanded != @state.simulationPanelExpanded) or
         (prevState.selectedLink != @state.selectedLink) or
+        (prevState.relationshipSymbols != @state.relationshipSymbols) or
         @forceRedrawLinks
       @diagramToolkit?.clear?()
       @_updateToolkit()


wip landing page

wip landing page

--- core/KDView.coffee
+++ core/KDView.coffee
@@ -201,18 +201,20 @@
 # DOM ELEMENT CREATION
 # #

-  setDomElement:(cssClass)->
-    cssClass = if cssClass then " #{cssClass}" else ""
+
+  setDomElement:(cssClass="")->
     {lazyDomId, tagName} = @getOptions()
-    if lazyDomId
-      @domElement = $("#{tagName}##{lazyDomId}")
-      @domElement.addClass "kdview#{cssClass}"
-      if @domElement?.length is 0
-        warn "No lazy DOM Element found with given id #{lazyDomId}."
-
-    @domElement ?= \
-      $ "<#{tagName} class='kdview#{cssClass}'></#{tagName} >"
-
+
+    el = document.getElementById lazyDomId  if lazyDomId
+
+    unless el?
+      warn "No lazy DOM Element found with given id #{lazyDomId}."  if lazyDomId
+      el = document.createElement tagName
+
+    for klass in "kdview #{cssClass}".split ' ' when klass.length
+      el.classList.add klass
+
+    @domElement = $ el

   setDomId:(id)->
     @domElement.attr "id",id
@@ -235,7 +237,7 @@
 # TRAVERSE DOM ELEMENT
 # #

-  getDomElement:()-> @domElement
+  getDomElement:-> @domElement

   getElement:-> @getDomElement()[0]


Update document of script

Update document of script

--- src/esa.coffee
+++ src/esa.coffee
@@ -1,11 +1,13 @@
 # Descriptipn
-#   Hubot script handle webhook and API of https://esa.io
+#  Hubot script handle webhook and API of https://esa.io
 #
 # Dependencies:
-#   None
+#  "crypto": "*"
 #
 # Commands:
-#    hubot esa stats - Retrieve stats of your team on esa
+#   hubot esa stats - Show stats of your team
+#   https://[yourteam].esa.io/posts/[post_id] - Show information of post
+#   https://[yourteam].esa.io/posts/[post_id]#comment-[comment_id] - Show comment
 #
 # Configuration:
 #   HUBOT_ESA_ACCESS_TOKEN
@@ -17,7 +19,6 @@
 #
 # Author:
 #   hmsk <k.hamasaki@gmail.com>
-#

 crypto = require 'crypto'


remove cid from language tab

remove cid from language tab

--- BackofficeBundle/Resources/public/coffee/LanguageView.coffee
+++ BackofficeBundle/Resources/public/coffee/LanguageView.coffee
@@ -1,5 +1,4 @@
 LanguageView = OrchestraView.extend(
-  tagName: "li"

   initialize: (options) ->
     @events = {}


Modified task details to not be so noisy.

--- src/glp.coffee
+++ src/glp.coffee
@@ -67,7 +67,7 @@
     allInputs = []

     gulp.task type, =>
-      winston.info 'Running task: ' + chalk.white type
+      winston.debug 'Running task: ' + chalk.white type

       outputs = @configuration.files[type]
       throw new Error 'No inputs defined for ' + type unless outputs?
@@ -78,6 +78,7 @@
         @outputs[type].push compiler.compile type, output, inputs
         allInputs = lodash.unique lodash.flatten allInputs.concat inputs

+    winston.info 'Configured task: ' + chalk.white type
     gulp.start type

     if @configuration.watch


Fix parameter asserting when the options passed through are undefined

--- src/app/Objects/StrictObject.coffee
+++ src/app/Objects/StrictObject.coffee
@@ -11,6 +11,14 @@
       throw new Error "Unable to create instance of Abstract class '#{@.__proto__.constructor.getName()}'"

     #Check that all config params were passed through correctly
-    AppEngine.Helpers.assertParametersExist @.__proto__.constructor.expectedParameters, conf
-    AppEngine.Helpers.applyToObject @__proto__.constructor.applyParameters, conf, @
+    if @.__proto__.constructor.expectedParameters.length > 0
+      if conf
+        AppEngine.Helpers.assertParametersExist @.__proto__.constructor.expectedParameters, conf
+      else
+        throw new Error "StrictObject: There are required parameters but the options are not defined"

+    AppEngine.Helpers.applyToObject @__proto__.constructor.applyParameters, conf, @ if conf
+
+
+
+


remove non-functioning check and add note.

editable by owner needs discussion lock + resolved post position check

--- resources/assets/coffee/react/modding-profile/posts.coffee
+++ resources/assets/coffee/react/modding-profile/posts.coffee
@@ -19,7 +19,6 @@
           [
             for post in @props.posts
               canModeratePosts = BeatmapDiscussionHelper.canModeratePosts(currentUser)
-              canBeDeleted = canModeratePosts || currentUser.id? == post.user_id

               discussionClasses = 'beatmap-discussion beatmap-discussion--preview'

@@ -53,8 +52,10 @@
                       user: @props.users[post.user_id]
                       read: true
                       lastEditor: @props.users[post.last_editor_id]
-                      canBeEdited: currentUser.is_admin || currentUser.id? == post.user_id
-                      canBeDeleted: canBeDeleted
+                      # FIXME: These permissions are more restrictive than the correct ones in discussion
+                      # because they don't have the right data to check.
+                      canBeEdited: currentUser.is_admin
+                      canBeDeleted: canModeratePosts
                       canBeRestored: canModeratePosts
                       currentUser: currentUser
             a


Issue #22. Correct location of thead/tbody add.

--- src/coffee/elements/table.coffee
+++ src/coffee/elements/table.coffee
@@ -168,18 +168,21 @@

       cell

-    # ## THead
-    # Expose the internal thead node
-    ret.add 'thead', thead

-    # ## TBody
-    # Expose the internal tbody node
-    ret.add 'tbody', tbody

     # ## Finalize
     # Finalize guarantees that thead and tbody and created when the node is fully instantiated
     ret.add 'finalize', ->
       init()
+
+      # ## THead
+      # Expose the internal thead node
+      ret.add 'thead', thead
+
+      # ## TBody
+      # Expose the internal tbody node
+      ret.add 'tbody', tbody
+
       ret

     ret


make flush to track-changes failsafe

make flush to track-changes failsafe

--- services/document-updater/app/coffee/HistoryManager.coffee
+++ services/document-updater/app/coffee/HistoryManager.coffee
@@ -13,8 +13,9 @@
 			return
 		RedisManager.getHistoryType doc_id, (err, projectHistoryType) ->
 			if err?
-				logger.error {err, doc_id}, "error getting history type"
-			else if projectHistoryType is "project-history"
+				logger.warn {err, doc_id}, "error getting history type"
+				# if there's an error continue and flush to track-changes for safety
+			if projectHistoryType is "project-history"
 				logger.debug {doc_id, projectHistoryType}, "skipping track-changes flush"
 			else
 				url = "#{Settings.apis.trackchanges.url}/project/#{project_id}/doc/#{doc_id}/flush"


CHG: dialog modal mask click can be disabled

--- frontend/javascripts/dialog/element.coffee
+++ frontend/javascripts/dialog/element.coffee
@@ -39,7 +39,7 @@

   _bind: ->
     @on 'click', (e) =>
-      @active = false if e.target == @
+      @active = false if @withCloseButton && e.target == @
       null

     @on 'click', ".tao-dialog-wrapper > .link-close, #{@closeSelector}", =>


Removing duplicate code from earlier merge

--- src/irc.coffee
+++ src/irc.coffee
@@ -74,7 +74,7 @@
     @bot.send command, strings...

   checkCanStart: ->
-    if not process.env.HUBOT_IRC_NICK or @robot.name
+    if not (process.env.HUBOT_IRC_NICK or @robot.name)
       throw new Error("HUBOT_IRC_NICK is not defined; try: export HUBOT_IRC_NICK='mybot'")
     else if not process.env.HUBOT_IRC_ROOMS
       throw new Error("HUBOT_IRC_ROOMS is not defined; try: export HUBOT_IRC_ROOMS='#myroom'")
@@ -148,18 +148,12 @@
     bot.addListener 'join', (channel, who) ->
         console.log('%s has joined %s', who, channel)
         user = self.createUser channel, who
-        self.receive new Robot.EnterMessage(user)
-
-        user = self.createUser channel, who
-        self.receive new Robot.EnterMessage(user)
+        self.receive new EnterMessage(user)

     bot.addListener 'part', (channel, who, reason) ->
         console.log('%s has left %s: %s', who, channel, reason)
         user = self.createUser channel, who
-        self.receive new Robot.LeaveMessage(user)
-
-        user = self.createUser channel, who
-        self.receive new Robot.LeaveMessage(user)
+        self.receive new LeaveMessage(user)

     bot.addListener 'kick', (channel, who, _by, reason) ->
         console.log('%s was kicked from %s by %s: %s', who, channel, _by, reason)


Support changing the topic in the adapter.

--- src/irc.coffee
+++ src/irc.coffee
@@ -16,6 +16,11 @@

     for str in strings
       @bot.say target, str
+
+  topic: (envelope, strings...) ->
+    data = strings.join " / "
+    channel = envelope.room
+    @bot.send 'TOPIC', channel, data

   emote: (envelope, strings...) ->
     # Use @notice if SEND_NOTICE_MODE is set


feat(app generator chore): adapt to `grunt-coffee-jshint@0.3.0`

--- generators/app/templates/@Gruntfile.coffee
+++ generators/app/templates/@Gruntfile.coffee
@@ -378,9 +378,7 @@

             options:

-                ##  NOTE:   Current grunt-coffee-jshint@0.2.1 uses coffee-jshint@0.0.14, which uses jshint@2.1.11, which does not yet support the 'browserify'
-                ##          option and others.
-                ##          The use of browserify and the UMD (Universal Module Definition) pattern implies the legimate use of the globals below.
+                ##  NOTE:   The use of browserify and the UMD (Universal Module Definition) pattern implies the legimate use of the globals below.
                 ##
                 ##  I would have liked to specify these globals and other jshint options through a '.jshintrc' file instead but have been unsuccessful so far.
                 ##
@@ -388,8 +386,6 @@
                 ##
                 globals: [
                                         'define'
-                                        'module'
-                                        'require'
                 ]

                 ##  Caveat: Using the extra variable `jshintOptions` to share a common set between the different targets below. Afaict this can't be done any
@@ -414,6 +410,7 @@
                 options:
                     jshintOptions:      jshintOptions.concat( [
                         ##              Environment options:
+                                        'browserify'
                                         'browser'
                                         'devel'
                     ] )


Add snippets to insert specs

Add snippets to insert specs

--- user/snippets.cson
+++ user/snippets.cson
@@ -63,6 +63,12 @@
 	Info:
 		prefix: "info"
 		body: 'console.info($1);$0'
+	Spec:
+		prefix: "it"
+		body: 'it("$1", function(){\n\t$2\n});'
+	"Spec Description":
+		prefix: "ds"
+		body: 'describe("$1", function(){\n\t$2\n});'

 # CoffeeScript/CSON


KodingKite: disable auto connect, connect only when needed and not connected yet

--- client/Main/kite/kodingkite.coffee
+++ client/Main/kite/kodingkite.coffee
@@ -31,10 +31,11 @@
     @forwardEvent @transport, 'close'
     @forwardEvent @transport, 'open'

-    @transport.connect() unless @isDisconnected
     @emit 'ready'

   tell: (rpcMethod, params, callback) ->
+
+    @connect()  unless @_connectAttempted or @isDisconnected

     unless @invalid

@@ -46,8 +47,8 @@

       Promise.reject
         name    : "KiteInvalid"
-        message : """Kite is invalid. This kite (#{name}) not exists
-                     or there is a problem with connection."""
+        message : "Kite is invalid. This kite (#{name}) not exists
+                   or there is a problem with connection."
         err     : @_invalid

@@ -60,7 +61,10 @@

   @constructors = {}

-  connect:    -> @transport?.connect()
+  connect: ->
+    @transport?.connect()
+    @_connectAttempted = yes
+
   disconnect: ->
     @isDisconnected = yes
     @transport?.disconnect()
@@ -71,4 +75,3 @@

     KD.utils.wait 1000, =>
       @transport?.connect()
-


fix typo

fix typo

--- client/app/components/panel.coffee
+++ client/app/components/panel.coffee
@@ -176,6 +176,6 @@
         return {
             accounts              : AccountStore.getAll()
             selectedAccount       : AccountStore.getSelectedOrDefault()
-            settinges              : SettingsStore.get()
+            settings              : SettingsStore.get()
             isLoadingReply        : not MessageStore.getByID(@props.messageID)?
         }


Update base.coffee

Update base.coffee

--- ui/tests/routers/base.coffee
+++ ui/tests/routers/base.coffee
@@ -1,3 +1,4 @@
 describe.skip('BaseRouter', ->
-
+    it('should call `beforeRoute` before each route', ->)
+    it('should close the previous controller, if there, before each route', ->)
 )


order for custom attributes

order for custom attributes

git-svn-id: 00f01ee4f729ccc52c3e336777c3e81b5adc88db@249000 ef392f78-ee14-0410-84e5-9db46baae5bb

--- app/scripts/widgets.coffee
+++ app/scripts/widgets.coffee
@@ -1,3 +1,4 @@
+
 Sidebar =
     _init: () ->

@@ -5,22 +6,26 @@
         @element.html '

'
         corpusObj = settings.corpora[corpus]

+
         $("
").html("

#{corpusObj.title}
").prependTo "#selected_sentence"
+
+        customData = pos: [], struct: []
+        unless $.isEmptyObject(corpusObj.custom_attributes)
+            [word, sentence] = @renderCustomContent wordData, sentenceData, corpusObj.custom_attributes, tokens
+            customData.pos = word
+            customData.struct = sentence
+
+        posData = []
         unless $.isEmptyObject(corpusObj.attributes)
-            $("#selected_word").append $("
").localeKey("word_attr")
-
-            posData = @renderCorpusContent("pos", wordData, sentenceData, corpusObj.attributes, tokens)
-            # posData.appendTo "#selected_word"
-            $("#selected_word").append posData
+            posData = @renderCorpusContent "pos", wordData, sentenceData, corpusObj.attributes, tokens, corpusObj.custom_attributes or {}, customData.pos
+        structData = []
         unless $.isEmptyObject(corpusObj.struct_attributes)
-            $("#selected_sentence").append $("
").localeKey("sentence_attr")
-
-            @renderCorpusContent("struct", wordData, sentenceData, corpusObj.struct_attributes, tokens).appendTo "#selected_sentence"
-
-        unless $.isEmptyObject(corpusObj.custom_attributes)
-            [word, sentence] = @renderCustomContent(wordData, sentenceData, corpusObj.custom_attributes, tokens)
-            word.appendTo "#selected_word"
-            sentence.appendTo "#selected_sentence"
+            structData = @renderCorpusContent "struct", wordData, sentenceData, corpusObj.struct_attributes, tokens, corpusObj.custom_attributes or {}, customData.struct
+
+        $("#selected_word").append $("
").localeKey("word_attr")
+        $("#selected_sentence").append $("
").localeKey("sentence_attr")
+        $("#selected_word").append posData
+        $("#selected_sentence").append structData

         @element.localize()
         @applyEllipse()
@@ -48,7 +53,7 @@

         ).appendTo(@element)

-    renderCorpusContent: (type, wordData, sentenceData, corpus_attrs, tokens) ->
+    renderCorpusContent: (type, wordData, sentenceData, corpus_attrs, tokens, customAttrs, customData) ->
         if type == "struct"
             pairs = _.pairs(sentenceData)

@@ -61,10 +66,22 @@
                     pairs.push([key, val])

         pairs = _.filter pairs, ([key, val]) -> corpus_attrs[key]
+        pairs = _.filter pairs, ([key, val]) -> not (corpus_attrs[key].displayType == "hidden" or corpus_attrs[key].displayType == "date_interval" or corpus_attrs[key].hideSidebar)
+
+        for custom in customData
+            pairs.push custom

         pairs.sort ([a], [b]) ->
-            ord1 = corpus_attrs[a].order
-            ord2 = corpus_attrs[b].order
+            if a of corpus_attrs
+                ord1 = corpus_attrs[a].order
+            else
+                ord1 = customAttrs[a].order
+
+            if b of corpus_attrs
+                ord2 = corpus_attrs[b].order
+            else
+                ord2 = customAttrs[b].order
+
             # first three cases to handle ord1 or ord2 being undefined
             if ord1 == ord2
                 return 0
@@ -77,26 +94,26 @@

         items = []
         for [key, value] in pairs
-            items = items.concat (@renderItem key, value, corpus_attrs[key], wordData, sentenceData, tokens).get?(0)
+            if key of customAttrs
+                items.push value
+            else
+                items = items.concat (@renderItem key, value, corpus_attrs[key], wordData, sentenceData, tokens).get?(0)

         items = _.compact items
         return $(items)

     renderCustomContent: (wordData, sentenceData, corpus_attrs, tokens) ->
-        struct_items = []
-        pos_items = []
+        structItems = []
+        posItems = []
         for key, attrs of corpus_attrs
-            output = @renderItem(key, null, attrs, wordData, sentenceData, tokens)
+            output = @renderItem(key, null, attrs, wordData, sentenceData, tokens).get?(0)
             if attrs.customType == "struct"
-                struct_items.push output
+                structItems.push [key, output]
             else if attrs.customType == "pos"
-                pos_items.push output
-        return [$(pos_items), $(struct_items)]
+                posItems.push [key, output]
+        return [posItems, structItems]

     renderItem: (key, value, attrs, wordData, sentenceData, tokens) ->
-
-        if attrs.displayType == "hidden" or attrs.displayType == "date_interval" or attrs.hideSidebar
-            return ""
         if attrs.label
             output = $("
:
")
         else


Fixed typo

Fixed typo

--- src/js/views/notification.coffee
+++ src/js/views/notification.coffee
@@ -58,6 +58,6 @@
     message: 'Factlink is loaded!'
     type_classes: 'fl-message-success fl-message-icon-time'

-Factlink.Views.Notifications.show (options) = ->
+Factlink.Views.Notifications.show = (options) ->
   message = new Factlink.Views.Notification options
   message.render()


Replace jquery_ujs with rails-ujs

Replace jquery_ujs with rails-ujs

Resolves #778

--- app/assets/javascripts/comfy/admin/cms/application.js.coffee
+++ app/assets/javascripts/comfy/admin/cms/application.js.coffee
@@ -1,5 +1,5 @@
+#= require rails-ujs
 #= require jquery3
-#= require jquery_ujs
 #= require jquery-ui
 #= require codemirror
 #= require codemirror/modes/css


Added focus on remove all when editing collaboration

Testing Plan
  * Enable collaborations by adding etherpad plugin
    with dummy info
  * Navigate to collaboration
  * Click on "Start a new collaboration"
  * Add some people, notice that "remove all" button appears
  * Click remove-all, notice that focus is consistent with remove single

Fixes CNVS-18511

Change-Id: I58b5b27898dd306e3bd0da12741409e71d5e2e42
Reviewed-on: https://gerrit.instructure.com/54071
Reviewed-by: Andrew Butterfield <c9c7a32d9a1e9779cfad12bed963960e7af36eac@instructure.com>
Tested-by: Jenkins
QA-Review: Steven Shepherd <e794458448443812fb2685675aab3bbd1a3891bc@instructure.com>
Product-Review: Andraia Allsop <ff4759604587803e867a0cdec27733973a67065f@instructure.com>

--- app/coffeescripts/views/collaborations/MemberListView.coffee
+++ app/coffeescripts/views/collaborations/MemberListView.coffee
@@ -102,6 +102,8 @@
     removeAll: (e) ->
       e.preventDefault()
       @collection.remove(@collection.models)
+      @currentIndex = 0
+      @updateFocus()

     # Internal: Show/hide the remove all btn based on collection size.
     #


Add Support for Symbols at the beginning of selected.

Closes #4

--- lib/highlighted-area-view.coffee
+++ lib/highlighted-area-view.coffee
@@ -41,7 +41,7 @@
     return unless @isWordSelected(editor.getSelection())

     text = _.escapeRegExp(editor.getSelectedText())
-    regex = new RegExp("\\w*\\b", 'gi')
+    regex = new RegExp("\\W*\\w*\\b", 'gi')
     result = regex.exec(text)

     return unless result?


hogeCharをhogeCharRegexpに名前変更

hogeCharをhogeCharRegexpに名前変更

--- lib/japanese-wrap-manager.coffee
+++ lib/japanese-wrap-manager.coffee
@@ -60,7 +60,7 @@
     @westernChar = /[\u0021-\u007E\u00A0-\u1FFF]/

     # Characters Not Starting a Line and Low Surrogate
-    @notStartingChar = new RegExp(
+    @notStartingCharRexgexp = new RegExp(
         @closingBracketChar.source + "|"  +
         @hyphenChar.source + "|" +
         @dividingPunctuationChar.source + "|" +
@@ -73,14 +73,14 @@
         @lowSurrogateChar.source
     )
     # Characters Not Ending a Line and High Surrogate
-    @notEndingChar = new RegExp(
+    @notEndingCharRegexp = new RegExp(
         @openingBracketChar.source + "|" +
         @highSurrogateChar.source
     )

     # Character Width
-    @zeroWidthChar = /[\u200B-\u200F\uDC00-\uDFFF\uFEFF]/
-    @halfWidthChar = /[\u0000-\u036F\u2000-\u2000A\u2122\uD800-\uD83F\uFF61-\uFFDC]/
+    @zeroWidthCharRegexp = /[\u200B-\u200F\uDC00-\uDFFF\uFEFF]/
+    @halfWidthCharRegexp = /[\u0000-\u036F\u2000-\u2000A\u2122\uD800-\uD83F\uFF61-\uFFDC]/
     # @fullWidthChar = /[^\u0000-\u036F\uFF61-\uFFDC]/

   # overwrite Display#findWrapColumn()
@@ -115,18 +115,18 @@
     return unless (line.length * 2) > sotfWrapColumn
     size = 0
     for wrapColumn in [0...line.length]
-      if @zeroWidthChar.test(line[wrapColumn])
+      if @zeroWidthCharRegexp.test(line[wrapColumn])
         continue
-      else if @halfWidthChar.test(line[wrapColumn])
+      else if @halfWidthCharRegexp.test(line[wrapColumn])
         size = size + 1
       else
         size = size + 2

       if size > sotfWrapColumn
-        if @notEndingChar.test(line[wrapColumn - 1])
+        if @notEndingCharRegexp.test(line[wrapColumn - 1])
           # search backward for the not ending character
           for column in [(wrapColumn - 1)...0]
-            return column unless @notEndingChar.test(line[column - 1])
+            return column unless @notEndingCharRegexp.test(line[column - 1])
           return wrapColumn
         else if @whitespaceChar.test(line[wrapColumn])
           # search forward for the start of a word past the boundary
@@ -138,10 +138,10 @@
           for column in [wrapColumn..0]
             return column + 1 unless @westernChar.test(line[column])
           return wrapColumn
-        else if @notStartingChar.test(line[wrapColumn])
+        else if @notStartingCharRexgexp.test(line[wrapColumn])
           # Character Not Starting a Line
           for column in [wrapColumn...0]
-            return column unless @notStartingChar.test(line[column])
+            return column unless @notStartingCharRexgexp.test(line[column])
           return wrapColumn
         else
           return wrapColumn


Use activated event instead of nextTick

Use activated event instead of nextTick

--- lib/markdown-preview-view.coffee
+++ lib/markdown-preview-view.coffee
@@ -40,7 +40,7 @@
     if atom.workspace?
       resolve()
     else
-      process.nextTick =>
+      atom.packages.once 'activated', =>
         resolve()
         @renderMarkdown()


Removes buggy handle config events.

Removes buggy handle config events.

--- lib/multi-wrap-guide-view.coffee
+++ lib/multi-wrap-guide-view.coffee
@@ -5,7 +5,6 @@
 module.exports =
 class MultiWrapGuideView extends View
   columns: []                 # Current column positions.
-  configSubs: null            # SubAtom object for config event handlers.
   currentCursorColumn: null   # Current mouse position in column position.
   currentCursorRow: null      # Current mouse position in row position.
   editor: null                # Attached editor.
@@ -41,8 +40,6 @@
     @linesView.find('div.multi-wrap-guide-view').empty().remove()
     @subs?.dispose()
     @subs = null
-    @configSubs?.dispose()
-    @configSubs = null

   # Private: Returns [left, top] offsets of mouse curosr from a given mouse event.
   offsetFromMouseEvent: (e) ->
@@ -78,7 +75,6 @@

   # Private: Sets up wrap guide event and command handlers.
   handleEvents: ->
-    @configSubs = @handleConfigEvents()
     redrawCallback = =>
       @redraw()

@@ -94,8 +90,6 @@
       @attach()
       redrawCallback()
     @subs.add @editor.onDidChangeGrammar =>
-      @configSubs.dispose()
-      @configSubs = @handleConfigEvents()
       @columns = @getColumns()
       @rows = @getRows()
       redrawCallback()
@@ -161,26 +155,6 @@
       scopeSelector = @getRootScopeSelector()
       @saveColumns scopeSelector
       @saveRows scopeSelector
-
-  # Private: Sets up wrap guide configuration change event handlers.
-  handleConfigEvents: ->
-    updateGuidesCallback = =>
-      [@rows, @columns] = [@getRows(), @getColumns()]
-      @locked = atom.config.get('multi-wrap-guide.locked')
-      @silent = atom.config.get('multi-wrap-guide.silent')
-      @enabled = atom.config.get('multi-wrap-guide.enabled')
-      @redraw()
-    subs = new SubAtom
-    scope = @editor.getRootScopeDescriptor()
-    scopedSubscribe = (key, callback) ->
-      subs.add atom.config.onDidChange key, scope: scope, callback
-    scopedSubscribe 'editor.preferredLineLength', updateGuidesCallback
-    scopedSubscribe 'multi-wrap-guide.columns', updateGuidesCallback
-    scopedSubscribe 'multi-wrap-guide.rows', updateGuidesCallback
-    subs.add atom.config.onDidChange 'multi-wrap-guide.locked', updateGuidesCallback
-    subs.add atom.config.onDidChange 'multi-wrap-guide.silent', updateGuidesCallback
-    subs.add atom.config.onDidChange 'multi-wrap-guide.enabled', updateGuidesCallback
-    subs

   # Private: Creates a new JQuery DOM element with given type and classes.
   createElement: (type, classes...) ->


Removed host specification for receiver listening so it will listen on all incoming IPs

--- lib/receivers/tcpReceiver.coffee
+++ lib/receivers/tcpReceiver.coffee
@@ -116,7 +116,7 @@
   #console.log { containerId: dockerHost, message: "Server Error", error: err.toString(), stack: err.stack}

   process.nextTick () ->
-    server.listen config.server?.port or 7000, config.server?.host or '127.0.0.1', () ->
+    server.listen config.server?.port or 7000, () ->
       startedCallback()

 exports.stop = () ->


Ignore trailing colons and whitespace when opening files from command line

--- src/browser/atom-application.coffee
+++ src/browser/atom-application.coffee
@@ -517,6 +517,8 @@
     return {pathToOpen} unless pathToOpen
     return {pathToOpen} if fs.existsSync(pathToOpen)

+    pathToOpen = pathToOpen.replace(/[:\s]+$/, '')
+
     [fileToOpen, initialLine, initialColumn] = path.basename(pathToOpen).split(':')
     return {pathToOpen} unless initialLine
     return {pathToOpen} unless parseInt(initialLine) >= 0


version tag

version tag

--- src/jasmine-given.coffee
+++ src/jasmine-given.coffee
@@ -1,3 +1,8 @@
+###
+jasmine-given @@VERSION@@
+Adds a Given-When-Then DSL to jasmine as an alternative style for specs
+site: https://github.com/searls/jasmine-given
+###
 ((jasmine) ->
   stringifyExpectation = (expectation) ->
     matches = expectation.toString().replace(/\n/g,'').match(/function\s?\(\)\s?{\s*(return\s+)?(.*?)(;)?\s*}/i)


FE:ActivityTicker fix styling issues

FE:ActivityTicker fix styling issues

--- client/Social/Activity/ContentDisplays/ActivityTicker.coffee
+++ client/Social/Activity/ContentDisplays/ActivityTicker.coffee
@@ -45,18 +45,14 @@
     unless @getConstructorName(origin) and @getConstructorName(subject)
       return console.warn "data is not valid"

-
-    eventObj =
     source = new KD.remote.api[subject.bongo_.constructorName] subject
     target = new KD.remote.api[origin.bongo_.constructorName] origin
     as     = "author"

-
     @fetchTags source, (err, tags)=>
       return log "discarding event, invalid data"  if err or not tags
       source.tags = tags
-      eventObj = {source, target, as}
-      @listController.addItem eventObj, 0
+      @listController.addItem {source, target, as}, 0

   addJoin: (data)->
     {member} = data


removed console error

removed console error

--- client/app/lib/providers/machinesettingsvmsharingview.coffee
+++ client/app/lib/providers/machinesettingsvmsharingview.coffee
@@ -76,7 +76,7 @@
     { profile: { nickname } } = user

     remote.api.SharedMachine[task] @machine.uid, [nickname], (err) =>
-      console.log 'errrr ', err
+
       return @showNotification err  if err

       kite   = @machine.getBaseKite()


XModule.loadModules only takes @el as argument now

--- common/lib/xmodule/xmodule/js/src/conditional/display.coffee
+++ common/lib/xmodule/xmodule/js/src/conditional/display.coffee
@@ -18,9 +18,9 @@
   render: (content) ->
     if content
       @el.html(content)
-      XModule.loadModules('display', @el)
+      XModule.loadModules(@el)
     else
       $.postWithPrefix "#{@url}/conditional_get", (response) =>
         @el.html(response.html)
-        XModule.loadModules('display', @el)
+        XModule.loadModules(@el)


test(action-overflow): unbind events on destroy

--- test/spec/directives/action-overflow.coffee
+++ test/spec/directives/action-overflow.coffee
@@ -60,6 +60,19 @@
         $$window.trigger 'touchstart'
         expect(scope.close).toHaveBeenCalled()

+      it 'should unbind after destroy', inject ($window) ->
+        $menu = element.find('bp-action-overflow-menu')
+        $actions = $menu.children()
+
+        events = $._data(element.get(0)).events
+        actionEvents = $._data($actions.get(0)).events
+        windowEvents = $._data($window).events
+
+        scope.$destroy()
+        expect(events.tap?).toBe false
+        expect(actionEvents.touchstart?).toBe false
+        expect(windowEvents.touchstart?).toBe false
+
     describe 'controller', ->
       it 'should open menu', ->
         $menu = element.find('bp-action-overflow-menu')