oops, remove focus from spec

oops, remove focus from spec

--- spec/installed-package-view-spec.coffee
+++ spec/installed-package-view-spec.coffee
@@ -62,7 +62,7 @@
       keybindingsTable = view.find('.package-keymap-table tbody')
       expect(keybindingsTable.children().length).toBe 0

-  fit "displays the correct enablement state", ->
+  it "displays the correct enablement state", ->
     packageCard = null

     waitsForPromise ->


Remove debug logging stmt

Remove debug logging stmt

--- coffee/main.coffee
+++ coffee/main.coffee
@@ -47,7 +47,6 @@
     e.originalEvent.preventDefault();
     document.onselectstart = -> false # disable selection while dragging
     p = position(e)
-    console.log p
     lc.begin(p.left, p.top)

   $c.mousemove (e) =>


reticulating lines

reticulating lines

--- coffee/main.coffee
+++ coffee/main.coffee
@@ -107,6 +107,7 @@
   Link: class Link
     constructor: (@parent, x, y, z) ->
       @shp = new Shapes.Rectangle(@parent.material.color, x, y, z, 25, 25)
+      #TODO if ln itself is clicked on this messes up selection logic
       @ln = new Shapes.Line(0xababab, 0, 0, 5, 25, 25)
       @shp.obj3d.userData = this
       @shp.obj3d.add(@ln.obj3d)
@@ -232,10 +233,15 @@
         e = ixs[0].object.userData
         console.log "! ebox select -- " + e.constructor.name
         console.log e
-
-        @makePlacingObject(e)
-        @ve.container.onmousemove = (eve) => @placingMove(eve)
-        @ve.container.onmousedown = (eve) => @placingDown(eve)
+        if e instanceof Link
+          console.log "! linking objects"
+          @ve.container.onmousemove = (eve) => @linkingMove0(eve)
+          @ve.container.onmousedown = (eve) => @linkingDown0(eve)
+        else
+          console.log "! placing objects"
+          @makePlacingObject(e)
+          @ve.container.onmousemove = (eve) => @placingMove(eve)
+          @ve.container.onmousedown = (eve) => @placingDown(eve)

     if ixs.length > 1 and
       ixs[1].object.userData instanceof Surface and
@@ -252,6 +258,16 @@
     @ve.container.onmousemove = null
     @ve.container.onmousedown = (eve) => @baseDown(eve)

+  linkingDown0: (event) ->
+    #TODO you are here
+    @ve.container.onmousemove = (eve) => @linkingMove1(eve)
+    @ve.container.onmousedown = (eve) => @linkingDown1(eve)
+
+  linkingDown1: (event) ->
+    #TODO you are here
+    @ve.container.onmousemove = null
+    @ve.container.onmousedown = (eve) => @baseDown(eve)
+
   #onmousemove handlers
   placingMove: (event) ->
     @updateMouse(event)
@@ -265,3 +281,13 @@
       @placingObject.shp.obj3d.position.y = bix[0].point.y
       @ve.render()

+  linkingMove0: (event) ->
+    @updateMouse(event)
+    console.log "! lm0"
+    #TODO you are here
+
+  linkingMove1: (event) ->
+    @updateMouse(event)
+    console.log "! lm1"
+    #TODO you are here
+


Remove debug

Remove debug

--- app/core/voicious.coffee
+++ app/core/voicious.coffee
@@ -75,7 +75,7 @@
             host : Config.Voicious.Sessions.Hostname.Internal
         }
         @i18n.init
-            debug: true
+            debug: false
             saveMissing: true
             resGetPath:  Path.join Config.Paths.Webroot, 'locales' ,'__lng__', '__ns__.json'
             lng: "en"


back to https

back to https

--- boot.coffee
+++ boot.coffee
@@ -19,7 +19,7 @@
 async = require('async')

 global.etabits = {
-  baseUrl: 'http://www.svuonline.org/isis'
+  baseUrl: 'https://www.svuonline.org/isis'
   log: log
   jsonMiddleware: require('body-parser').json()
   models: {}


GameObject: Add load_recursive, get_descendants and get_top_ancestor. Fix related issues.

--- engine/gameobject.coffee
+++ engine/gameobject.coffee
@@ -300,6 +300,7 @@
         {
             recursive=true
             behaviours=true
+            new_parent=@parent
             scene = @scene
         } = options ? {}
         # TODO: Is it better or more efficient to instance a new object
@@ -319,6 +320,9 @@
         n.avg_poly_area = @avg_poly_area
         n.avg_poly_length = @avg_poly_length
         n.behaviours = []
+        if new_parent?
+            n.parent = new_parent
+            n.parent.children.push n
         @body._clone_to(n)

         # Warning! This only works reliably
@@ -327,7 +331,7 @@
         if n.materials and scene != this.scene
             for i in [0...materials.length]
                 n.materials[i] = materials[i].clone_to_scene scene
-
+
         n.scene = null
         scene?.add_object n, @name
         if behaviours
@@ -336,7 +340,7 @@
         # Adding children after ensures objects don't need to be sorted
         if recursive
             for child in @children
-                child = child.clone(options)
+                child = child.clone({options, new_parent: n})
                 child.parent = n
                 children.push child
         n.body.instance()
@@ -344,6 +348,11 @@
             child.body.instance()
         return n

+    set_parent: (parent, options) ->
+        if @parent?
+            @scene.clear_parent this, options
+        @scene.make_parent parent, this, options
+
     parent_to: (parent, options) ->
         if @parent?
             @scene.clear_parent this, options
@@ -352,8 +361,28 @@
     clear_parent: (options) ->
         @scene.clear_parent this, options

+    get_top_ancestor: (top_level_parents=[]) ->
+        ob = this
+        while ob.parent? and ob.parent not in top_level_parents
+            ob = ob.parent
+        return ob
+
+    get_descendants: ->
+        children_lists = [@children]
+        @_fill_children_lists_recursive children_lists
+        return Array.concat children_lists
+
+    _fill_children_lists_recursive: (children_lists) ->
+        for c in @children
+            children_lists.push c.children
+            c._fill_children_lists_recursive children_lists
+        return
+
     load: (options) ->
         return @scene?.load_objects [this], options
+
+    load_recursive: (options) ->
+        return @scene?.load_objects @get_descendants(), options

     # Removes the object from the scene. It does NOT delete the object itself.
     remove: (recursive) ->


If class has @extends attribute generate a different callback name (bubble/tunnel)

--- source/core/event.coffee
+++ source/core/event.coffee
@@ -99,8 +99,8 @@
     # Default Callback
     unless callback
       constructor = if args.length is 1 then @constructor else args[1].constructor
-      class_base = @_classBase constructor
-      callback = "on#{class_base.toClassName()}#{event.toClassName()}"
+      base = if constructor.extends then constructor.name else constructor.base
+      callback = "on#{base.toClassName()}#{event.toClassName()}"

     # Add type
     args[0].eventType = type


Reset filter box when a site is saved to remove confusion

--- admin/controllers/filter-box.coffee
+++ admin/controllers/filter-box.coffee
@@ -24,6 +24,7 @@
     @siteId = ''
     @query = ''
     @setup()
+    @filter()
     @

   setup: ->
@@ -85,5 +86,4 @@
       siteId: @siteId

-
 module.exports = FilterBox


Add test for bad step values

Add test for bad step values

--- spec/GetHistogram.coffee
+++ spec/GetHistogram.coffee
@@ -60,6 +60,56 @@
       testutils.getCanvasWithImageNoShift inSrc, (c) ->
         canvas.beginGroup groupId
         step.send 2
+        canvas.send c
+        canvas.endGroup()
+
+    it 'should calculate histograms even if step is higher than image size', (done) ->
+      groupId = 'huge-step'
+      groups = []
+      out.once 'begingroup', (group) ->
+        groups.push group
+      out.once 'endgroup', (group) ->
+        groups.pop()
+      out.once 'data', (res) ->
+        chai.expect(groups).to.be.eql ['huge-step']
+        chai.expect(res).to.be.deep.equal
+        chai.expect(res).to.be.an 'object'
+        hists = 'rgbayhslc'
+        for hist in hists
+          expected = fixtures.histogram.colorful[hist]
+          for val, i in res[hist]
+            chai.expect(val, "histogram-#{hist}").to.be.closeTo expected[i], 0.001
+        done()
+
+      inSrc = 'colorful-octagon.png'
+      testutils.getCanvasWithImageNoShift inSrc, (c) ->
+        canvas.beginGroup groupId
+        step.send 1000000
+        canvas.send c
+        canvas.endGroup()
+
+    it 'should calculate histograms even if step is not valid', (done) ->
+      groupId = 'invalid-step'
+      groups = []
+      out.once 'begingroup', (group) ->
+        groups.push group
+      out.once 'endgroup', (group) ->
+        groups.pop()
+      out.once 'data', (res) ->
+        chai.expect(groups).to.be.eql ['invalid-step']
+        chai.expect(res).to.be.deep.equal
+        chai.expect(res).to.be.an 'object'
+        hists = 'rgbayhslc'
+        for hist in hists
+          expected = fixtures.histogram.colorful[hist]
+          for val, i in res[hist]
+            chai.expect(val, "histogram-#{hist}").to.be.closeTo expected[i], 0.001
+        done()
+
+      inSrc = 'colorful-octagon.png'
+      testutils.getCanvasWithImageNoShift inSrc, (c) ->
+        canvas.beginGroup groupId
+        step.send 0
         canvas.send c
         canvas.endGroup()


Stop blinking after each test

Stop blinking after each test

--- spec/StateToColor.coffee
+++ spec/StateToColor.coffee
@@ -20,6 +20,10 @@
     portalConfig = JSON.parse fs.readFileSync path.resolve(__dirname, '../portals.json'), 'utf-8'
     portals.send portalConfig.portals

+  afterEach ->
+    # Stop blinking
+    c.shutdown()
+
   describe 'receiving a neutral portal', ->
     it 'should set the color correctly', (done) ->
       color.on 'data', (color) ->


:lipstick:

:lipstick:

--- spec/apm-cli-spec.coffee
+++ spec/apm-cli-spec.coffee
@@ -567,7 +567,7 @@
       atomSpawn = spyOn(child_process, 'spawn').andReturn({ stdout: { on: -> }, stderr: { on: -> }, on: -> })
       apm.run(['test'])

-      waitsFor 'waiting for init to complete', ->
+      waitsFor 'waiting for test to complete', ->
         atomSpawn.callCount is 1

       runs ->


Correct spec comment

Correct spec comment

--- spec/apm-cli-spec.coffee
+++ spec/apm-cli-spec.coffee
@@ -522,7 +522,7 @@
         callback = jasmine.createSpy('callback')
         apm.run(['init', '--package', 'fake-package'], callback)

-        waitsFor 'waiting for develop to complete', ->
+        waitsFor 'waiting for init to complete', ->
           callback.callCount is 1

         runs ->


Fix typo in config

Fix typo in config

--- lib/caniuse.coffee
+++ lib/caniuse.coffee
@@ -29,7 +29,7 @@
       type:'boolean'
       default:  false
     showAndroid:
-      title: 'Android Browser'
+      title: 'Show Android Browser'
       type:'boolean'
       default:  true
     showOpMob:


Date fixes.

Date fixes.

* Handle invalid day names.
* Only use the next weekday if the selected day is on a weekend.

--- app/models/day.coffee
+++ app/models/day.coffee
@@ -16,10 +16,11 @@
       @date = DAYS[date.getDay()]
     else if typeof date is 'string'
       @date = _.find(DAYS, (day) -> day.name.toLowerCase() is date.toLowerCase())
+      @date = DAYS[new Date().getDay()] unless @date?
     else
       @date = DAYS[new Date().getDay()]

-    @date = @nextWeekday()
+    @date = @nextWeekday() if @isWeekend()

   name: ->
     @date.name
@@ -39,6 +40,9 @@
     else
       DAYS[@date.index + 1]

+  isWeekend: ->
+    @date.index is 6 or @date.index is 0
+
   attributes: ->
     name: @name()
     previousWeekday: @previousWeekday()


Integrate Geordi v2

Integrate Geordi v2

--- app/lib/analytics.coffee
+++ app/lib/analytics.coffee
@@ -28,8 +28,8 @@
     url: 'http://127.0.0.1:3000/api/events/',
     type: 'POST',
     contentType: 'application/json; charset=utf-8',
-    contentLength: length+2,
-    data: "{"+JSON.stringify(eventData)+"}",
+    contentLength: length,
+    data: JSON.stringify(eventData),
     dataType: 'json'
   }