Correct service code for general feedback.

--- src/models.coffee
+++ src/models.coffee
@@ -809,7 +809,7 @@
                 if @get 'accessibility_enabled'
                     service_code = 11
                 else
-                    service_code = 55
+                    service_code = 1363
             json.service_code = service_code
             json.service_object_id = @get('unit').get 'id'
             json.service_object_type = 'http://www.hel.fi/servicemap/v2'


Add option for empty line color in parser

--- src/parser.coffee
+++ src/parser.coffee
@@ -266,7 +266,7 @@

           else if stack[stack.length - 1]?.type in ['indent', 'segment', undefined] and
               hasSomeTextAfter(lines, i)
-            block = new model.Block 0, 'yellow', helper.BLOCK_ONLY
+            block = new model.Block 0, @opts.emptyLineColor, helper.BLOCK_ONLY

             head = head.append block.start
             head = head.append block.end


Finds file path using a couple of rules

Finds file path using a couple of rules

--- grammars/log.cson
+++ grammars/log.cson
@@ -9,11 +9,21 @@
 patterns: [
     {
         comment: 'Bare minimum to make the log file look good. I will look into its syntax some other time.'
-        match: '(\\\\)[\\w|@]*'
+        match: '(\\\\)[\\w@]*'
         name: 'support.function.general.latex.log'
     }
     {
-        match: 'Undefined control sequence\\.'
+        match: '\\!.*$' # Doesn't work
         name: 'invalid.illegal.latex.log'
     }
+    {
+        include: '#filePath'
+    }
 ]
+
+repository:
+  filePath: {
+    comment: 'Finds a file path in the log file. Assumes paths start with a space/bracket followed by `/` (date conflict otherwise)'
+    name: 'support.filepath.latex'
+    match: '(?<=[\\s\\(\\{\\[\\<]|^)(\\/|\\~\\/|\\.\\/)([^\\s\\(\\)\\[\\]\\{\\}\\:]+\\/)*?([^\\s\\(\\)\\[\\]\\{\\}\\:])+'
+  }


fixes #1752: passing POSIX-style arguments to scripts through the CLI

--- optparse.coffee
+++ optparse.coffee
@@ -25,10 +25,11 @@
   # for interpreting the options object.
   parse: (args) ->
     options = arguments: [], literals: []
-    args    = normalizeArguments args
+    originalArgs = args
+    args = normalizeArguments args
     for arg, i in args
       if arg is '--'
-        options.literals = args[(i + 1)..]
+        options.literals = originalArgs[(1 + originalArgs.indexOf '--')..]
         break
       isOption = !!(arg.match(LONG_FLAG) or arg.match(SHORT_FLAG))
       matchedRule = no
@@ -40,7 +41,7 @@
           break
       throw new Error "unrecognized option: #{arg}" if isOption and not matchedRule
       if not isOption
-        options.arguments = args.slice i
+        options.arguments = originalArgs[(originalArgs.indexOf arg)..]
         break
     options


Fixed incorrect lastPunch on failed out-punch

--- src/models/punch.coffee
+++ src/models/punch.coffee
@@ -321,7 +321,8 @@
         else
           return true
       last = user.lastPunch 'out', 'vacation', 'unpaid', 'sick'
-      time = last.times[0].tz(user.timetable.timezone.name)
+      time = last.times[1].tz(user.timetable.timezone.name) or
+             last.times[0].tz(user.timetable.timezone.name)
       return "You cannot punch out before punching in. Your last
               out-punch was at *#{time.format('h:mma')} on
               #{time.format('dddd, MMMM Do')}*."


* check already be streamable before add this feature to database class

--- src/nosql-stream.coffee
+++ src/nosql-stream.coffee
@@ -16,12 +16,11 @@
   constructor: (aClass)->
     if (this not instanceof StreamNoSQL)
       vParentClass = isInheritedFrom aClass, AbstractNoSQL
-      if vParentClass
-        if vParentClass isnt StreamNoSQL
-          inheritsDirectly vParentClass, StreamNoSQL
+      if vParentClass and not isInheritedFrom aClass, StreamNoSQL
+        inheritsDirectly vParentClass, StreamNoSQL
         return aClass
       else
-        throw new InvalidArgumentError("class should be inherited from AbstractNoSQL")
+        throw new InvalidArgumentError("class should be inherited from AbstractNoSQL or already streamable")
       return aClass
     super
   readStream: (options, makeData)->


update projects

update projects

--- atom/projects.cson
+++ atom/projects.cson
@@ -23,6 +23,16 @@
     "/mnt/Peng/Jordan/Code/hacking-tacoscript/babel/packages/babylon"
     "/mnt/Peng/Jordan/Code/hacking-tacoscript/babel/packages/babel-core"
     "/mnt/Peng/Jordan/Code/hacking-tacoscript/babel"
+    "/home/jord/code/tacoscript-hacking/babel/packages/babylon"
+    "/home/jord/code/repos/git/dotfiles"
+    "/home/jord/code/tacoscript-hacking/tacoscript/packages/horchata"
+    "/home/jord/.nvm/versions/io.js/v3.3.1/lib/node_modules/mocha"
+    "/home/jord/code/tacoscript-hacking/tacoscript/packages/tacoscript/node_modules/mocha-fixtures-generic"
+    "/home/jord/code/tacoscript-hacking/tacoscript/packages/tacoscript"
+    "/home/jord/code/tacoscript-hacking/tacoscript"
+    "/home/jord/code/tacoscript-hacking/tacoscript-ast-playground"
+    "/home/jord/code/tacoscript-hacking/tacoscript/packages/tacoscript-cli"
+    "/home/jord/code/tacoscript-hacking"
   ]
 "tree-view-doubleclick":
   title: "tree-view-doubleclick"


adding shop events

adding shop events

--- src/coffee/controllers/player-ctrl.coffee
+++ src/coffee/controllers/player-ctrl.coffee
@@ -85,6 +85,8 @@
       'item-find': ['icon-feather']
       'item-enchant': ['fa-magic']
       'item-switcheroo': ['icon-magnet']
+      'shop': ['fa-money']
+      'shop-fail': ['fa-money']
       'profession': ['fa-child']
       'explore': ['fa-globe']
       'levelup': ['icon-universal-access']


Introduce some light namespacing for AI.

--- ai.coffee
+++ ai.coffee
@@ -20,7 +20,7 @@
 		when "move" then add_move(event.data.x, event.data.y)
 		when "go"
 			ai_name = event.data.ai
-			postMessage(ais[ai_name]())
+			postMessage(ais[ai_name].move())

 # Given an x,y coordinate in the 81 square space,
 # return the subboard it's on (0 1 2/3 4 5/6 7 8)
@@ -30,10 +30,10 @@
 get_square_on_subboard = (x,y) ->
 	3 * (y % 3) + (x % 3)

-first_unfilled = (subboard_index) ->
+ais.first_unfilled = (subboard_index) ->
 	return i for v,i in boards[subboard_index] when v is 0

-unfilled_squares = (subboard_index) ->
+ais.unfilled_squares = (subboard_index) ->
 	return (i for v,i in boards[subboard_index] when v is 0)

 # This is the call to mutate the board from user-space
@@ -44,13 +44,20 @@
 	subboard_next.push square_index
 	return

-# This is the call to get the next move to make
-ais["random"] = () ->
+##
+# The idea of the AI dict is that each namespace can contain
+# local AI functions if necessary without polluting the file-scope namespace.
+# Does that matter? Who knows!
+##
+
+# The random ai simply makes a random move on the currently active subboard.
+ais["random"] = {}
+ais["random"].move = () ->
 	subboard = subboard_next[-1..][0]

 	# selection = first_unfilled(subboard)

-	options = unfilled_squares(subboard)
+	options = ais.unfilled_squares(subboard)
 	console.log options
 	selection = options[Math.random() * options.length // 1]

@@ -59,12 +66,17 @@
 	add_move(x,y)
 	return [x,y]

-ais["greedy"] = () ->
+# The greedy ai picks the first open square on the currently active subboard.
+ais["greedy"] = {}
+ais["greedy"].move = () ->
 	subboard = subboard_next[-1..][0]
-	selection = first_unfilled(subboard)
+	selection = ais.first_unfilled(subboard)
 	x = selection % 3 + 3 * (subboard % 3)
 	y = selection // 3 + 3 * (subboard // 3)
 	add_move(x,y)
 	return [x,y]

+# The focused ai will play the best move for the current active subboard.
+# That is, it 'focuses' on winning subboards.
+
 reset()


Removed unnecessary pause and fail-proofed proceed button detection

--- client/test/lib/environments/vm.coffee
+++ client/test/lib/environments/vm.coffee
@@ -78,7 +78,7 @@
   terminateVm: (browser) ->

       terminateSelector       = '.advanced .terminate'
-      proceedSelector         = '.kdbutton.solid.red.medium'
+      proceedSelector         = '.kdmodal.with-buttons .kdbutton.solid.red.medium'
       terminatedLabelSelector = '.terminated'

       helpers.beginTest(browser)
@@ -89,9 +89,10 @@
       browser
         .waitForElementVisible  terminateSelector, 20000
         .click                  terminateSelector
-        .pause                  2500
         .waitForElementVisible  proceedSelector, 20000
         .click                  proceedSelector
         .waitForElementVisible  terminatedLabelSelector, 100000
         .assert.containsText   terminatedLabelSelector, "successfully deleted"
         .end()
+
+


Fixing docstring params.

Fixing docstring params.


:snake::snowman: Updated in browser at strd6.github.io/editor

--- pixie.cson
+++ pixie.cson
@@ -1,2 +1,2 @@
-version: "0.2.0"
+version: "0.3.1"
 entryPoint: "main"


improved project params

improved project params

--- src/coffee/util.coffee
+++ src/coffee/util.coffee
@@ -33,7 +33,12 @@
       if _.size(parts) is 1
         res[parts[0]] = true
       else if _.size(parts) is 2
-        res[parts[0]] = parts[1]
+        if res[parts[0]]? and _.isArray(res[parts[0]])
+          res[parts[0]] = res[parts[0]].concat(parts[1])
+        else if res[parts[0]]?
+          res[parts[0]] = [res[parts[0]], parts[1]]
+        else
+          res[parts[0]] = parts[1]
       else
         throw new Error("Invalid projects parameter definition (only one `=` is allowed)")


fix livereload of import/includes of jade and stylus

--- gulp/build.coffee
+++ gulp/build.coffee
@@ -121,8 +121,8 @@
 gulp.task "stylus", ->
   gulp.src(srcPaths.stylus)
     .pipe(plumber())
-    .pipe(changed(destPaths.stylesheets, {extension: ".css"}))
     .pipe(stylus({use: [nib()]}))
+    .pipe(changed(destPaths.html, {hasChanged: changed.compareSha1Digest}))
     .pipe(gulp.dest(destPaths.stylesheets))
     .pipe gulpIf(shared.isWatching, liveReload())

@@ -140,11 +140,12 @@
 gulp.task "jade", ->
   gulp.src(srcPaths.jade)
     .pipe(plumber())
-    .pipe(changed(destPaths.html, {extension: ".html"}))
     .pipe(jade(
       locals: jadeLocals
       pretty: true
-    )).pipe(gulp.dest(destPaths.html))
+    ))
+    .pipe(changed(destPaths.html, {hasChanged: changed.compareSha1Digest}))
+    .pipe(gulp.dest(destPaths.html))
     .pipe gulpIf(shared.isWatching, liveReload())

 gulp.task "html", ->


hiding the title in the question view (for now?)

--- dkobo/koboform/static/js/xlform/XLF.view.surveyApp.coffee
+++ dkobo/koboform/static/js/xlform/XLF.view.surveyApp.coffee
@@ -69,7 +69,10 @@
         @emptySurveyXlfRowSelector = new XLF.RowSelector(el: @$el.find(".expanding-spacer-between-rows").get(0), survey: @survey, ngScope: @ngScope)
       @emptySurveyXlfRowSelector.expand()

-    viewUtils.makeEditable @, @survey.settings, '.form-title', property:'form_title'
+    if @features.displayTitle
+      viewUtils.makeEditable @, @survey.settings, '.form-title', property:'form_title'
+    else
+      @$(".survey-header__inner").hide()

     # see this page for info on what should be in a form_id
     # http://opendatakit.org/help/form-design/guidelines/
@@ -198,6 +201,7 @@
   features:
     multipleQuestions: true
     skipLogic: true
+    displayTitle: true
     copyToLibrary: false
     surveySettings: true

@@ -205,6 +209,7 @@
   features:
     multipleQuestions: false
     skipLogic: false
+    displayTitle: false
     copyToLibrary: false
     surveySettings: false


Workspace: Don't need to check pane created state.

--- client/app/CommonViews/workspace/views/workspacefloatingpanelauncher.coffee
+++ client/app/CommonViews/workspace/views/workspacefloatingpanelauncher.coffee
@@ -24,7 +24,6 @@
       @createPanes()

   click: ->
-    @createPanes()  unless @panesCreated
     @toggleClass "active"

   createPanes: ->


Calendar view fix for check-ins.

Calendar view fix for check-ins.

--- packages/pixelartacademy-practice/calendar/checkincomponent.coffee
+++ packages/pixelartacademy-practice/calendar/checkincomponent.coffee
@@ -13,22 +13,22 @@
     PAA.Practice.CheckIn.documents.findOne checkIn._id

   showEntry: ->
-    checkIn = @data()
+    checkIn = @currentData()

     @showImage() or checkIn.text

   showImage: ->
-    checkIn = @data()
+    checkIn = @currentData()

     checkIn.artwork or checkIn.image or checkIn.post

   textStyle: ->
-    checkIn = @data()
+    checkIn = @currentData()

     color: "##{checkIn.character.colorObject().getHexString()}"

   linkColor: ->
-    checkIn = @data()
+    checkIn = @currentData()

     # Link should be 2 shades lighter than the text.
     checkIn.character.colorObject 2


fix test

fix test

--- components/auth_modal/test/view.coffee
+++ components/auth_modal/test/view.coffee
@@ -91,6 +91,7 @@

   describe '#submit', ->
     beforeEach ->
+      sinon.stub location, 'assign'
       sinon.stub location, 'reload'
       @view.validateForm = -> true

@@ -98,6 +99,7 @@
       @view.user = new LoggedOutUser

     afterEach ->
+      location.assign.restore()
       location.reload.restore()

     it 'submits to signup when in that mode', ->


Agent: testing switcher mods

Agent: testing switcher mods

--- dashing-contrib/lib/dashing-contrib/assets/widgets/switcher/switcher.coffee
+++ dashing-contrib/lib/dashing-contrib/assets/widgets/switcher/switcher.coffee
@@ -89,8 +89,8 @@
     @handle = setInterval(()->
       # Hide all at first - then show the current and ensure it uses table-cell display type
       #self.$elements.hide()
-      self.$elements.hide(300)
-      $(self.$elements[self.curPos]).show(300).css('display', 'table-cell')
+      self.$elements.hide(333)
+      $(self.$elements[self.curPos]).show(333).css('display', 'table-cell')

       # Increase the position or reset back to zero
       self.curPos += 1


Clear SERVERID cookie when reconnecting gracefully

--- services/web/public/coffee/ide/connection/ConnectionManager.coffee
+++ services/web/public/coffee/ide/connection/ConnectionManager.coffee
@@ -204,4 +204,6 @@
 		_reconnectGracefullyNow: () ->
 			@gracefullyReconnecting = true
 			@reconnectGracefullyStarted = null
+			# Clear cookie so we don't go to the same backend server
+			$.cookie("SERVERID", "", { expires: -1, path: "/" })
 			@reconnectImmediately()


Rename command to compositCommand in command interpreter

--- src/extensions/command-interpreter.coffee
+++ src/extensions/command-interpreter.coffee
@@ -7,9 +7,9 @@
     @parser = PEG.buildParser(fs.read(require.resolve 'command-interpreter/commands.pegjs'))

   eval: (editor, string) ->
-    command = @parser.parse(string)
-    @lastRelativeAddress = command if command.isRelativeAddress()
-    command.execute(editor)
+    compositeCommand = @parser.parse(string)
+    @lastRelativeAddress = compositeCommand if compositeCommand.isRelativeAddress()
+    compositeCommand.execute(editor)

   repeatRelativeAddress: (editor) ->
     @lastRelativeAddress?.execute(editor)


more fair meta-tags

more fair meta-tags

--- models/mixins/meta_overrides.coffee
+++ models/mixins/meta_overrides.coffee
@@ -22,6 +22,18 @@

 metaOverrides = (model) ->

+  'design-miami-2015':
+    title: 'Design Miami/ 2015 | Artsy'
+    description: 'From established modernists to emerging desginers, your first look at the preeminent design fair in Miami'
+
+  'art-basel-in-miami-beach-2015':
+    title: 'Art Basel in Miami Beach 2015 | Artsy'
+    description: 'Find out what Paul Kasmin Gallery, KÖNIG GALERIE, ShanghART Gallery, and others are bringing to Miami Beach for the 14th U.S. edition of the renowned Swiss fair'
+
+  'focus-miami-2015':
+    title: 'Art Miami / Satellite Fairs 2015 | Artsy'
+    description: 'Explore our extensive coverage of Miami Art Week with highlights from the leading events happening in South Beach'
+
   'abu-dhabi-art-2015':
     title: 'Abu Dhabi Art 2015 | Artsy'
     description: 'Discover works from emerging and established galleries—including Hauser & Wirth, Acquavella, and The Third Line—soon to be on view in the United Arab Emirates’ capital.'


Removed bad spacing

Removed bad spacing

--- src/scripts/virustotal.coffee
+++ src/scripts/virustotal.coffee
@@ -35,7 +35,7 @@
             vt_json = JSON.parse(body)

             if vt_json.response_code == 1
-              summary = """ VirusTotal Result: #{vt_json.resource}
+              summary = """VirusTotal Result: #{vt_json.resource}
               - Scanned at: #{vt_json.scan_date}
               - Results:    #{vt_json.positives}/#{vt_json.total}
               - Link:       #{vt_json.permalink}
@@ -63,7 +63,7 @@
             vt_json = JSON.parse(body)

             if vt_json.response_code == 1
-              summary = """ VirusTotal URL Result: #{vt_json.url}
+              summary = """VirusTotal URL Result: #{vt_json.url}
               - Scanned at: #{vt_json.scan_date}
               - Results:    #{vt_json.positives}/#{vt_json.total}
               - Link:       #{vt_json.permalink}
@@ -93,7 +93,7 @@

               if vt_json.response_code == 1

-                summary = """ VirusTotal IP Result: #{ip}
+                summary = """VirusTotal IP Result: #{ip}
                 - Detected Communicating Samples: #{vt_json.detected_communicating_samples.length}
                 - Detected URLs #{vt_json.detected_urls.length}


Fixes jasmine-given path

Fixes jasmine-given path

--- spec-e2e/login_spec.coffee
+++ spec-e2e/login_spec.coffee
@@ -1,6 +1,6 @@
 protractor = require("protractor")
 require "protractor/jasminewd"
-require 'jasmine-given-actual'
+require 'jasmine-given'

 describe "my angular app", ->
   ptor = protractor.getInstance()


Require testutils

Require testutils

--- spec/CanvasToBuffer.coffee
+++ spec/CanvasToBuffer.coffee
@@ -2,8 +2,10 @@
 unless noflo.isBrowser()
   chai = require 'chai' unless chai
   CanvasToBuffer = require '../components/CanvasToBuffer.coffee'
+  testutils = require './testutils'
 else
   CanvasToBuffer = require 'noflo-image/components/CanvasToBuffer.js'
+  testutils = require 'noflo-image/spec/testutils.js'

 describe 'CanvasToBuffer component', ->
   c = null


Module: add options to assurer

Module: add options to assurer

--- node_modules_koding/jraphical/lib/module.coffee
+++ node_modules_koding/jraphical/lib/module.coffee
@@ -350,17 +350,22 @@
           Relationship.count rdef, callback

   getAssurer_ = do ->
-    addIt =(context, adder, target, callback)->
-      context[adder] target, (err)->
+    addIt = (context, adder, target, options, callback)->
+      context[adder] target, options, (err)->
         if err
           callback err
         else
           callback null, target
     (constructor, name, def)->
-      (target, callback)->
-        [callback, target] = [target, callback] unless callback
+      (target, options, callback)->
+
+        [callback, options] = [options, callback] unless callback
+        [target, callback]  = [callback, target]  unless callback
+        options ?= {}
+
         fetcher = @getInterfaceName 'fetch', name
-        adder = @getInterfaceName 'add', name
+        adder   = @getInterfaceName 'add', name
+
         selector =
           if target?
             targetId    : target.getId()
@@ -383,14 +388,14 @@
             }, (err)->
               callback null, module
           else if target
-            addIt this, adder, target, callback
+            addIt this, adder, target, options, callback
           else
             target = new def.targetType
             target.save (err)=>
               if err
                 callback err
               else
-                addIt this, adder, target, callback
+                addIt this, adder, target, options, callback

   remove_ = @::remove
   remove:(callback=->)->


jraphical: remove extraneous whitespace

jraphical: remove extraneous whitespace

--- node_modules_koding/jraphical/lib/module.coffee
+++ node_modules_koding/jraphical/lib/module.coffee
@@ -454,8 +454,6 @@
         @constructor.emit 'RemovedFromCollection', this
         callback err

-
-
   beginGraphlet:-> new Graphlet nodes: [@]

   getFlag = (key, val)->


Whoops

Whoops

--- spec/find-view-spec.coffee
+++ spec/find-view-spec.coffee
@@ -334,7 +334,6 @@
           $('.find-and-replace .btn-all').click()
           expect(findView.resultCounter.text()).toEqual('no results')
           expect(editor.getText()).not.toMatch /items/
-          window.x = editor.getText()
           expect(editor.getText().match(/\bcats\b/g).length).toMatch 6
           expect(editor.getSelectedBufferRange()).toEqual [[2, 0], [2, 0]]


Fix the tag input event type for tags added via a blur event

--- modules/tag-input/main/index.coffee
+++ modules/tag-input/main/index.coffee
@@ -124,6 +124,7 @@
     if not @_.autocomplete
       @input.on 'blur', 'hx.tag-input', (event) =>
         if @input.value().length > 0 and not hasError()
+          _.userEvent = true
           @add(@input.value(), undefined)

     @input.on 'focus', 'hx.tag-input', (event) =>


Test localsync implementation of Backbone.sync

This largely tests that localsync delegates its operations to the underlying store.

--- spec/localsync_spec.coffee
+++ spec/localsync_spec.coffee
@@ -2,15 +2,85 @@

 describe 'localsync', ->
   describe 'standard Backbone.sync methods', ->
-    xit 'creates records', ->
-    xit 'reads records', ->
-    xit 'updates records', ->
-    xit 'deletes records', ->
+    describe 'creating records', ->
+      it 'creates records', ->
+        create = spyOn(window.Store.prototype, 'create')
+        model = id: 1
+        window.localsync 'create', model, {success: (->), error: (->)}
+        expect(create).toHaveBeenCalledWith model
+
+      it 'does not overwrite existing models with fetch(add: true) unless passed merge: true', ->
+        create = spyOn(window.Store.prototype, 'find').andReturn id: 1
+        create = spyOn(window.Store.prototype, 'create')
+        window.localsync 'create', {id: 1}, {success: (->), error: (->), add: true}
+        expect(create).not.toHaveBeenCalled()
+        window.localsync 'create', {id: 1}, {success: (->), error: (->), add: true, merge: true}
+        expect(create).toHaveBeenCalled()
+
+      it 'supports marking a new record dirty', ->
+        model = id: 1
+        create = spyOn(window.Store.prototype, 'create').andReturn model
+        dirty = spyOn(window.Store.prototype, 'dirty')
+        window.localsync 'create', model, {success: (->), error: (->), dirty: true}
+        expect(create).toHaveBeenCalledWith model
+        expect(dirty).toHaveBeenCalledWith model
+
+    describe 'reading records', ->
+      it 'reads models', ->
+        find = spyOn(window.Store.prototype, 'find')
+        model = new window.Backbone.Model id: 1
+        window.localsync 'read', model, {success: (->), error: (->)}
+        expect(find).toHaveBeenCalledWith model
+
+      it 'reads collections', ->
+        findAll = spyOn(window.Store.prototype, 'findAll')
+        window.localsync 'read', new window.Backbone.Collection, {success: (->), error: (->)}
+        expect(findAll).toHaveBeenCalled()
+
+    describe 'updating records', ->
+      it 'updates records', ->
+        update = spyOn(window.Store.prototype, 'update')
+        model = id: 1
+        window.localsync 'update', model, {success: (->), error: (->)}
+        expect(update).toHaveBeenCalledWith model
+
+      it 'supports marking an updated record dirty', ->
+        model = id: 1
+        update = spyOn(window.Store.prototype, 'update')
+        dirty = spyOn(window.Store.prototype, 'dirty')
+        window.localsync 'update', model, {success: (->), error: (->), dirty: true}
+        expect(update).toHaveBeenCalledWith model
+        expect(dirty).toHaveBeenCalledWith model
+
+    describe 'deleting records', ->
+      it 'deletes records', ->
+        destroy = spyOn(window.Store.prototype, 'destroy')
+        model = id: 1
+        window.localsync 'delete', model, {success: (->), error: (->)}
+        expect(destroy).toHaveBeenCalledWith model
+
+      it 'supports marking a dirty record destroyed', ->
+        model = id: 1
+        destroy = spyOn(window.Store.prototype, 'destroy')
+        destroyed = spyOn(window.Store.prototype, 'destroyed')
+        window.localsync 'delete', model, {success: (->), error: (->), dirty: true}
+        expect(destroy).toHaveBeenCalledWith model
+        expect(destroyed).toHaveBeenCalledWith model

   describe 'extra methods', ->
-    xit 'clears out all records from the store', ->
-    xit 'reports whether or not it hasDirtyOrDestroyed', ->
+    it 'clears out all records from the store', ->
+      clear = spyOn(window.Store.prototype, 'clear')
+      window.localsync 'clear', {}, {success: (->), error: (->)}

-  describe 'options', ->
-    xit 'ignores callbacks with the ignoreCallbacks option set', ->
-    xit 'uses the dirty option to mark the dirty/clean state on update and destroy', ->
+    it 'reports whether or not it hasDirtyOrDestroyed', ->
+      clear = spyOn(window.Store.prototype, 'hasDirtyOrDestroyed')
+      window.localsync 'hasDirtyOrDestroyed', {}, {success: (->), error: (->)}
+
+
+  describe 'callbacks', ->
+    it 'ignores callbacks when the ignoreCallbacks option is set', ->
+      callback = jasmine.createSpy 'callback'
+      window.localsync 'create', {id: 1}, {success: callback, error: callback, ignoreCallbacks: true}
+      expect(callback).not.toHaveBeenCalled()
+      window.localsync 'create', {id: 1}, {success: callback, error: callback}
+      expect(callback).toHaveBeenCalled()


Clean up motions specs

Clean up motions specs

--- spec/operators-spec.coffee
+++ spec/operators-spec.coffee
@@ -52,22 +52,22 @@
       expect(editor.getText()).toBe "012345\n\nabcdef"

   describe "the s keybinding", ->
-    it "deletes the character to the right and enters insert mode", ->
-      editor.setText("012345")
-      editor.setCursorScreenPosition([0, 0])
-
-      keydown('s', element: editor[0])
-      expect(editor).toHaveClass 'insert-mode'
-      expect(editor.getText()).toBe '12345'
-      expect(editor.getCursorScreenPosition()).toEqual [0, 0]
-      expect(vimState.getRegister('"').text).toBe '0'
-
-    it "deletes count characters to the right and enters insert mode", ->
+    beforeEach ->
       editor.setText("012345")
       editor.setCursorScreenPosition([0, 1])

+    it "deletes the character to the right and enters insert mode", ->
+      keydown('s', element: editor[0])
+
+      expect(editor).toHaveClass 'insert-mode'
+      expect(editor.getText()).toBe '02345'
+      expect(editor.getCursorScreenPosition()).toEqual [0, 1]
+      expect(vimState.getRegister('"').text).toBe '1'
+
+    it "deletes count characters to the right and enters insert mode", ->
       keydown('3', element: editor[0])
       keydown('s', element: editor[0])
+
       expect(editor).toHaveClass 'insert-mode'
       expect(editor.getText()).toBe '045'
       expect(editor.getCursorScreenPosition()).toEqual [0, 1]
@@ -93,6 +93,7 @@

         keydown('d', element: editor[0])
         keydown('d', element: editor[0])
+
         expect(editor.getText()).toBe "12345\n\nABCDE"
         expect(editor.getCursorScreenPosition()).toEqual([1,0])
         expect(vimState.getRegister('"').text).toBe "abcde\n"
@@ -100,30 +101,32 @@
       it "deletes the last line", ->
         editor.setText("12345\nabcde\nABCDE")
         editor.setCursorScreenPosition([2,1])
-        keydown('d', element: editor[0])
-        keydown('d', element: editor[0])
+
+        keydown('d', element: editor[0])
+        keydown('d', element: editor[0])
+
         expect(editor.getText()).toBe "12345\nabcde"
         expect(editor.getCursorScreenPosition()).toEqual([1,0])

-      describe "when the second d is prefixed by a count", ->
+    describe "when the second d is prefixed by a count", ->
+      beforeEach ->
+        editor.setText("12345\nabcde\nABCDE\nQWERT")
+        editor.setCursorScreenPosition([1,1])
+
+        keydown('d', element: editor[0])
+        keydown('2', element: editor[0])
+        keydown('d', element: editor[0])
+
+      it "deletes n lines, starting from the current", ->
+        expect(editor.getText()).toBe "12345\nQWERT"
+        expect(editor.getCursorScreenPosition()).toEqual([1,0])
+
+      describe "with undo", ->
         beforeEach ->
-          editor.setText("12345\nabcde\nABCDE\nQWERT")
-          editor.setCursorScreenPosition([1,1])
-
-          keydown('d', element: editor[0])
-          keydown('2', element: editor[0])
-          keydown('d', element: editor[0])
-
-        it "deletes n lines, starting from the current", ->
-          expect(editor.getText()).toBe "12345\nQWERT"
-          expect(editor.getCursorScreenPosition()).toEqual([1,0])
-
-        describe "with undo", ->
-          beforeEach ->
-            keydown('u', element: editor[0])
-
-          it "undoes both lines", ->
-            expect(editor.getText()).toBe "12345\nabcde\nABCDE\nQWERT"
+          keydown('u', element: editor[0])
+
+        it "undoes both lines", ->
+          expect(editor.getText()).toBe "12345\nabcde\nABCDE\nQWERT"

     describe "when followed by an h", ->
       it "deletes the previous letter on the current line", ->
@@ -206,40 +209,44 @@

   describe "the c keybinding", ->
     describe "when followed by a c", ->
+      beforeEach ->
+        editor.setText("12345\nabcde\nABCDE")
+
       it "deletes the current line and enters insert mode", ->
-        editor.setText("12345\nabcde\nABCDE")
-        editor.setCursorScreenPosition([1,1])
-
-        keydown('c', element: editor[0])
-        keydown('c', element: editor[0])
+        editor.setCursorScreenPosition([1,1])
+
+        keydown('c', element: editor[0])
+        keydown('c', element: editor[0])
+
         expect(editor.getText()).toBe "12345\nABCDE"
         expect(editor.getCursorScreenPosition()).toEqual([1,0])
         expect(editor).not.toHaveClass 'command-mode'
         expect(editor).toHaveClass 'insert-mode'

       it "deletes the last line and enters insert mode", ->
-        editor.setText("12345\nabcde\nABCDE")
         editor.setCursorScreenPosition([2,1])
-        keydown('c', element: editor[0])
-        keydown('c', element: editor[0])
+
+        keydown('c', element: editor[0])
+        keydown('c', element: editor[0])
+
         expect(editor.getText()).toBe "12345\nabcde"
         expect(editor.getCursorScreenPosition()).toEqual([1,0])
         expect(editor).not.toHaveClass 'command-mode'
         expect(editor).toHaveClass 'insert-mode'

-      describe "when the second c is prefixed by a count", ->
-        it "deletes n lines, starting from the current, and enters insert mode", ->
-          editor.setText("12345\nabcde\nABCDE\nQWERT")
-          editor.setCursorScreenPosition([1,1])
-
-          keydown('c', element: editor[0])
-          keydown('2', element: editor[0])
-          keydown('c', element: editor[0])
-
-          expect(editor.getText()).toBe "12345\nQWERT"
-          expect(editor.getCursorScreenPosition()).toEqual([1,0])
-          expect(editor).not.toHaveClass 'command-mode'
-          expect(editor).toHaveClass 'insert-mode'
+    describe "when the second c is prefixed by a count", ->
+      it "deletes n lines, starting from the current, and enters insert mode", ->
+        editor.setText("12345\nabcde\nABCDE\nQWERT")
+        editor.setCursorScreenPosition([1,1])
+
+        keydown('c', element: editor[0])
+        keydown('2', element: editor[0])
+        keydown('c', element: editor[0])
+
+        expect(editor.getText()).toBe "12345\nQWERT"
+        expect(editor.getCursorScreenPosition()).toEqual([1,0])
+        expect(editor).not.toHaveClass 'command-mode'
+        expect(editor).toHaveClass 'insert-mode'

     describe "when followed by an h", ->
       it "deletes the previous letter on the current line and enters insert mode", ->
@@ -499,6 +506,7 @@

     it "switches to insert mode and shifts to the right", ->
       editor.setCursorScreenPosition [0, 0]
+
       keydown('a', element: editor[0])

       expect(editor.getCursorScreenPosition()).toEqual [0,1]
@@ -506,6 +514,7 @@

     it "doesn't linewrap", ->
       editor.setCursorScreenPosition [0, 3]
+
       keydown('a', element: editor[0])

       expect(editor.getCursorScreenPosition()).toEqual [0,3]


Fix remaining specs

Fix remaining specs

--- spec/tree-view-spec.coffee
+++ spec/tree-view-spec.coffee
@@ -1449,7 +1449,7 @@
             expect(fs.existsSync(filePath)).toBeTruthy()

           describe "when the target already exists", ->
-            it "appends a number to the destination directory name", ->
+            it "appends a number to the destination file name", ->
               LocalStorage['tree-view:copyPath'] = JSON.stringify([filePath])

               dirView.click()
@@ -1467,25 +1467,28 @@
               expect(fs.existsSync(numberedFileName1)).toBeTruthy()
               expect(fs.existsSync(filePath)).toBeTruthy()

-        xdescribe "when a directory with a period is selected", ->
-          it "creates a copy of the original file in the selected directory", ->
+        describe "when a directory with a period is selected", ->
+          [dotDirPath] = []
+
+          beforeEach ->
             dotDirPath = path.join(rootDirPath, "test.dir")
             fs.makeTreeSync(dotDirPath)
+
+            atom.project.setPaths([rootDirPath]) # Force test.dir to show up
+
+          it "creates a copy of the original file in the selected directory", ->
             LocalStorage['tree-view:copyPath'] = JSON.stringify([filePath])

             dotDirView = $(treeView.roots[0].entries).find('.directory:contains(test\\.dir)')
             dotDirView.click()
-            console.log dotDirView
             atom.commands.dispatch(treeView.element, "tree-view:paste")

             expect(fs.existsSync(path.join(dotDirPath, path.basename(filePath)))).toBeTruthy()
             expect(fs.existsSync(filePath)).toBeTruthy()

           describe "when the target already exists", ->
-            it "appends a number to the destination directory name", ->
-              dotDirPath = path.join(rootDirPath, "test.dir")
+            it "appends a number to the destination file name", ->
               dotFilePath = path.join(dotDirPath, "test.file.txt")
-              fs.makeTreeSync(dotDirPath)
               fs.writeFileSync(dotFilePath, "doesn't matter .")
               LocalStorage['tree-view:copyPath'] = JSON.stringify([dotFilePath])


remove unsupported files in jquery.shapeshift v2.0

--- ajax/libs/jquery.shapeshift/2.0/jquery.shapeshift.coffee
+++ ajax/libs/jquery.shapeshift/2.0/jquery.shapeshift.coffee
@@ -1,724 +0,0 @@
-#  Project: jQuery.Shapeshift
-#  Description: Align elements to grid with drag and drop.
-#  Author: Scott Elwood
-#  Maintained By: We the Media, inc.
-#  License: MIT
-
-(($, window, document) ->
-  pluginName = "shapeshift"
-  defaults =
-    # The Basics
-    selector: "*"
-
-    # Features
-    enableDrag: true
-    enableCrossDrop: true
-    enableResize: true
-    enableTrash: false
-
-    # Grid Properties
-    align: "center"
-    colWidth: null
-    columns: null
-    minColumns: 1
-    autoHeight: true
-    maxHeight: null
-    minHeight: 100
-    gutterX: 10
-    gutterY: 10
-    paddingX: 10
-    paddingY: 10
-
-    # Animation
-    animated: true
-    animateOnInit: false
-    animationSpeed: 225
-    animationThreshold: 100
-
-    # Drag/Drop Options
-    dragClone: false
-    deleteClone: true
-    dragRate: 100
-    dragWhitelist: "*"
-    crossDropWhitelist: "*"
-    cutoffStart: null
-    cutoffEnd: null
-    handle: false
-
-    # Customize CSS
-    cloneClass: "ss-cloned-child"
-    activeClass: "ss-active-child"
-    draggedClass: "ss-dragged-child"
-    placeholderClass: "ss-placeholder-child"
-    originalContainerClass: "ss-original-container"
-    currentContainerClass: "ss-current-container"
-    previousContainerClass: "ss-previous-container"
-
-  class Plugin
-    constructor: (@element, options) ->
-      @options = $.extend {}, defaults, options
-      @globals = {}
-      @$container = $(element)
-
-      if @errorCheck()
-        @init()
-
-
-    # ----------------------------
-    # errorCheck:
-    # Determine if there are any conflicting options
-    # ----------------------------
-    errorCheck: ->
-      options = @options
-      errors = false
-      error_msg = "Shapeshift ERROR:"
-
-      # If there are no available children, a colWidth must be set
-      if options.colWidth is null
-        $children = @$container.children(options.selector)
-
-        if $children.length is 0
-          errors = true
-          console.error "#{error_msg} option colWidth must be specified if Shapeshift is initialized with no active children."
-
-      return !errors
-
-    # ----------------------------
-    # Init:
-    # Only enable features on initialization,
-    # then call a full render of the elements
-    # ----------------------------
-    init: ->
-      @createEvents()
-      @setGlobals()
-      @setIdentifier()
-      @setActiveChildren()
-      @enableFeatures()
-      @gridInit()
-      @render()
-      @afterInit()
-
-    # ----------------------------
-    # createEvents:
-    # Triggerable events on the container
-    # which run certain functions
-    # ----------------------------
-    createEvents: ->
-      options = @options
-      $container = @$container
-
-      $container.off("ss-arrange").on "ss-arrange", (e, trigger_drop_finished = false) => @render(false, trigger_drop_finished)
-      $container.off("ss-rearrange").on "ss-rearrange", => @render(true)
-      $container.off("ss-setTargetPosition").on "ss-setTargetPosition", => @setTargetPosition()
-      $container.off("ss-destroy").on "ss-destroy", => @destroy()
-
-    # ----------------------------
-    # setGlobals:
-    # Globals that only need to be set on initialization
-    # ----------------------------
-    setGlobals: ->
-      # Prevent initial animation if applicable
-      @globals.animated = @options.animateOnInit
-
-    # ----------------------------
-    # afterInit:
-    # Take care of some dirty business
-    # ----------------------------
-    afterInit: ->
-      # Return animation to normal
-      @globals.animated = @options.animated
-
-    # ----------------------------
-    # setIdentifier
-    # Create a random identifier to tie to this container so that
-    # it is easy to unbind the specific resize event from the browser
-    # ----------------------------
-    setIdentifier: ->
-      @identifier = "shapeshifted_container_" + Math.random().toString(36).substring(7)
-      @$container.addClass(@identifier)
-
-    # ----------------------------
-    # enableFeatures:
-    # Enables options features
-    # ----------------------------
-    enableFeatures: ->
-      @enableResize() if @options.enableResize
-      @enableDragNDrop() if @options.enableDrag or @options.enableCrossDrop
-
-    # ----------------------------
-    # setActiveChildren:
-    # Make sure that only the children set by the
-    # selector option can be affected by Shapeshifting
-    # ----------------------------
-    setActiveChildren: ->
-      options = @options
-
-      # Add active child class to each available child element
-      $children = @$container.children(options.selector)
-      active_child_class = options.activeClass
-      total = $children.length
-
-      for i in [0...total]
-        $($children[i]).addClass(active_child_class)
-
-      @setParsedChildren()
-
-      # Detect if there are any colspans wider than
-      # the column options that were set
-      columns = options.columns
-      for i in [0...@parsedChildren.length]
-        colspan = @parsedChildren[i].colspan
-
-        min_columns = options.minColumns
-        if colspan > columns and colspan > min_columns
-          options.minColumns = colspan
-          console.error "Shapeshift ERROR: There are child elements that have a larger colspan than the minimum columns set through options.\noptions.minColumns has been set to #{colspan}"
-
-    # ----------------------------
-    # setParsedChildren:
-    # Calculates and returns commonly used
-    # attributes for all the active children
-    # ----------------------------
-    setParsedChildren: ->
-      $children = @$container.find("." + @options.activeClass).filter(":visible")
-      total = $children.length
-
-      parsedChildren = []
-      for i in [0...total]
-        $child = $($children[i])
-        child =
-          i: i
-          el: $child
-          colspan: parseInt($child.attr("data-ss-colspan")) || 1
-          height: $child.outerHeight()
-        parsedChildren.push child
-      @parsedChildren = parsedChildren
-
-    # ----------------------------
-    # setGrid:
-    # Calculates the dimensions of each column
-    # and determines to total number of columns
-    # ----------------------------
-    gridInit: ->
-      gutter_x = @options.gutterX
-
-      unless @options.colWidth >= 1
-        # Determine single item / col width
-        first_child = @parsedChildren[0]
-        fc_width = first_child.el.outerWidth()
-        fc_colspan = first_child.colspan
-        single_width = (fc_width - ((fc_colspan - 1) * gutter_x)) / fc_colspan
-        @globals.col_width = single_width + gutter_x
-      else
-        @globals.col_width = @options.colWidth + gutter_x
-
-    # ----------------------------
-    # render:
-    # Determine the active children and
-    # arrange them to the calculated grid
-    # ----------------------------
-    render: (reparse = false, trigger_drop_finished) ->
-      @setGridColumns()
-      @arrange(reparse, trigger_drop_finished)
-
-    # ----------------------------
-    # setGrid:
-    # Calculates the dimensions of each column
-    # and determines to total number of columns
-    # ----------------------------
-    setGridColumns: ->
-      # Common
-      globals = @globals
-      options = @options
-      col_width = globals.col_width
-      gutter_x = options.gutterX
-      padding_x = options.paddingX
-      inner_width = @$container.innerWidth() - (padding_x * 2)
-
-      # Determine how many columns there currently can be
-      minColumns = options.minColumns
-      columns = options.columns || Math.floor (inner_width + gutter_x) / col_width
-      if minColumns and minColumns > columns
-        columns = minColumns
-      globals.columns = columns
-
-      # Columns cannot exceed children
-      children_count = @parsedChildren.length
-      if columns > children_count
-        columns = children_count
-
-      # Calculate the child offset from the left
-      globals.child_offset = padding_x
-      switch options.align
-        when "center"
-          grid_width = (columns * col_width) - gutter_x
-          globals.child_offset += (inner_width - grid_width) / 2
-
-        when "right"
-          grid_width = (columns * col_width) - gutter_x
-          globals.child_offset += (inner_width - grid_width)
-
-    # ----------------------------
-    # arrange:
-    # Animates the elements into their calcluated positions
-    # ----------------------------
-    arrange: (reparse, trigger_drop_finished) ->
-      @setParsedChildren() if reparse
-
-      globals = @globals
-      options = @options
-
-      # Common
-      $container = @$container
-      child_positions = @getPositions()
-
-      parsed_children = @parsedChildren
-      total_children = parsed_children.length
-
-      animated = globals.animated and total_children <= options.animationThreshold
-      animation_speed = options.animationSpeed
-      dragged_class = options.draggedClass
-
-      # Arrange each child element
-      for i in [0...total_children]
-        $child = parsed_children[i].el
-        attributes = child_positions[i]
-        is_dragged_child = $child.hasClass(dragged_class)
-
-        if is_dragged_child
-          placeholder_class = options.placeholderClass
-          $child = $child.siblings("." + placeholder_class)
-
-        if animated and !is_dragged_child
-          $child.stop(true, false).animate attributes, animation_speed, ->
-        else
-          $child.css attributes
-
-
-      if trigger_drop_finished
-        if animated
-          setTimeout (->
-            $container.trigger("ss-drop-complete")
-          ), animation_speed
-        else
-          $container.trigger("ss-drop-complete")
-      $container.trigger("ss-arranged")
-
-      # Set the container height
-      if options.autoHeight
-        container_height = globals.container_height
-        max_height = options.maxHeight
-        min_height = options.minHeight
-
-        if min_height and container_height < min_height
-          container_height = min_height
-        else if max_height and container_height > max_height
-          container_height = max_height
-
-        $container.height container_height
-
-    # ----------------------------
-    # getPositions:
-    # Go over each child and determine which column they
-    # fit into and return an array of their x/y dimensions
-    # ----------------------------
-    getPositions: (include_dragged = true) ->
-      globals = @globals
-      options = @options
-      gutter_y = options.gutterY
-      padding_y = options.paddingY
-      dragged_class = options.draggedClass
-
-      parsed_children = @parsedChildren
-      total_children = parsed_children.length
-
-      # Store the height for each column
-      col_heights = []
-      for i in [0...globals.columns]
-        col_heights.push padding_y
-
-      # ----------------------------
-      # savePosition
-      # Takes a child which has been correctly placed in a
-      # column and saves it to that final x/y position.
-      # ----------------------------
-      savePosition = (child) =>
-        col = child.col
-        colspan = child.colspan
-        offset_x = (child.col * globals.col_width) + globals.child_offset
-        offset_y = col_heights[col]
-
-        positions[child.i] = left: offset_x, top: offset_y
-        col_heights[col] += child.height + gutter_y
-
-        if colspan >= 1
-          for j in [1...colspan]
-            col_heights[col + j] = col_heights[col]
-
-      # ----------------------------
-      # determineMultiposition
-      # Children with multiple column spans will need special
-      # rules to determine if they are currently able to be
-      # placed in the grid.
-      # ----------------------------
-      determineMultiposition = (child) =>
-        # Only use the columns that this child can fit into
-        possible_cols = col_heights.length - child.colspan + 1
-        possible_col_heights = col_heights.slice(0).splice(0, possible_cols)
-
-        chosen_col = undefined
-        for offset in [0...possible_cols]
-          col = @lowestCol(possible_col_heights, offset)
-          colspan = child.colspan
-          height = col_heights[col]
-
-          kosher = true
-
-          # Determine if it is able to be placed at this col
-          for span in [1...colspan]
-            next_height = col_heights[col + span]
-
-            # The next height must not be higher
-            if height < next_height
-              kosher = false
-              break
-
-          if kosher
-            chosen_col = col
-            break
-
-        return chosen_col
-
-      # ----------------------------
-      # recalculateSavedChildren
-      # Sometimes child elements cannot save the first time around,
-      # iterate over those children and determine if its ok to place now.
-      # ----------------------------
-      saved_children = []
-      recalculateSavedChildren = =>
-        to_pop = []
-        for saved_i in [0...saved_children.length]
-          saved_child = saved_children[saved_i]
-          saved_child.col = determineMultiposition(saved_child)
-
-          if saved_child.col >= 0
-            savePosition(saved_child)
-            to_pop.push(saved_i)
-
-        # Popeye. Lol.
-        for pop_i in [to_pop.length - 1..0] by -1
-          index = to_pop[pop_i]
-          saved_children.splice(index,1)
-
-      # ----------------------------
-      # determinePositions
-      # Iterate over all the parsed children and determine
-      # the calculations needed to get its x/y value.
-      # ----------------------------
-      positions = []
-      do determinePositions = =>
-        for i in [0...total_children]
-          child = parsed_children[i]
-
-          unless !include_dragged and child.el.hasClass(dragged_class)
-            if child.colspan > 1
-              child.col = determineMultiposition(child)
-            else
-              child.col = @lowestCol(col_heights)
-
-            if child.col is undefined
-              saved_children.push child
-            else
-              savePosition(child)
-
-            recalculateSavedChildren()
-
-      # Store the container height since we already have the data
-      if options.autoHeight
-        grid_height = col_heights[@highestCol(col_heights)] - gutter_y
-        globals.container_height = grid_height + padding_y
-
-      return positions
-
-    # ----------------------------
-    # enableDrag:
-    # Optional feature.
-    # Initialize dragging.
-    # ----------------------------
-    enableDragNDrop: ->
-      options = @options
-
-      $container = @$container
-      active_class = options.activeClass
-      dragged_class = options.draggedClass
-      placeholder_class = options.placeholderClass
-      original_container_class = options.originalContainerClass
-      current_container_class = options.currentContainerClass
-      previous_container_class = options.previousContainerClass
-      delete_clone = options.deleteClone
-      drag_rate = options.dragRate
-      drag_clone = options.dragClone
-      clone_class = options.cloneClass
-
-      $selected = $placeholder = $clone = selected_offset_y = selected_offset_x = null
-      dragging = false
-
-      if options.enableDrag
-        $container.children("." + active_class).filter(options.dragWhitelist).draggable
-          addClasses: false
-          containment: 'document'
-          handle: options.handle
-          zIndex: 9999
-
-          start: (e, ui) ->
-            # Set $selected globals
-            $selected = $(e.target)
-
-            if drag_clone
-              $clone = $selected.clone(true).insertBefore($selected).addClass(clone_class)
-
-            $selected.addClass(dragged_class)
-
-            # Create Placeholder
-            selected_tag = $selected.prop("tagName")
-            $placeholder = $("<#{selected_tag} class='#{placeholder_class}' style='height: #{$selected.height()}px; width: #{$selected.width()}px'></#{selected_tag}>")
-
-            # Set current container
-            $selected.parent().addClass(original_container_class).addClass(current_container_class)
-
-            # For manually centering the element with respect to mouse position
-            selected_offset_y = $selected.outerHeight() / 2
-            selected_offset_x = $selected.outerWidth() / 2
-
-          drag: (e, ui) =>
-            if !dragging and !(drag_clone and delete_clone and $("." + current_container_class)[0] is $("." + original_container_class)[0])
-              # Append placeholder to container
-              $placeholder.remove().appendTo("." + current_container_class)
-
-              # Set drag target and rearrange everything
-              $("." + current_container_class).trigger("ss-setTargetPosition")
-
-              # Disallow dragging from occurring too much
-              dragging = true
-              window.setTimeout ( ->
-                dragging = false
-              ), drag_rate
-
-            # Manually center the element with respect to mouse position
-            ui.position.left = e.pageX - $selected.parent().offset().left - selected_offset_x;
-            ui.position.top = e.pageY - $selected.parent().offset().top - selected_offset_y;
-
-          stop: ->
-            $original_container = $("." + original_container_class)
-            $current_container = $("." + current_container_class)
-            $previous_container = $("." + previous_container_class)
-
-            # Clear globals
-            $selected.removeClass(dragged_class)
-            $("." + placeholder_class).remove()
-
-            if drag_clone
-              if delete_clone and $("." + current_container_class)[0] is $("." + original_container_class)[0]
-                $clone.remove()
-                $("." + current_container_class).trigger("ss-rearrange")
-              else
-                $clone.removeClass(clone_class)
-
-            # Trigger Events
-            if $original_container[0] is $current_container[0]
-              $current_container.trigger("ss-rearranged", $selected)
-            else
-              $original_container.trigger("ss-removed", $selected)
-              $current_container.trigger("ss-added", $selected)
-
-            # Arrange dragged item into place and clear container classes
-            $original_container.trigger("ss-arrange").removeClass(original_container_class)
-            $current_container.trigger("ss-arrange", true).removeClass(current_container_class)
-            $previous_container.trigger("ss-arrange").removeClass(previous_container_class)
-
-            $selected = $placeholder = null
-
-
-      if options.enableCrossDrop
-        $container.droppable
-          accept: options.crossDropWhitelist
-          tolerance: 'intersect'
-          over: (e) =>
-            $("." + previous_container_class).removeClass(previous_container_class)
-            $("." + current_container_class).removeClass(current_container_class).addClass(previous_container_class)
-            $(e.target).addClass(current_container_class)
-
-          drop: (e, selected) =>
-            if @options.enableTrash
-              $original_container = $("." + original_container_class)
-              $current_container = $("." + current_container_class)
-              $previous_container = $("." + previous_container_class)
-              $selected = $(selected.helper)
-
-              $current_container.trigger("ss-trashed", $selected)
-              $selected.remove()
-
-              $original_container.trigger("ss-rearrange").removeClass(original_container_class)
-              $current_container.trigger("ss-rearrange").removeClass(current_container_class)
-              $previous_container.trigger("ss-arrange").removeClass(previous_container_class)
-
-    # ----------------------------
-    # getTargetPosition:
-    # Determine the target position for the selected
-    # element and arrange it into place
-    # ----------------------------
-    setTargetPosition: ->
-      options = @options
-
-      unless options.enableTrash
-        dragged_class = options.draggedClass
-
-        $selected = $("." + dragged_class)
-        $start_container = $selected.parent()
-        parsed_children = @parsedChildren
-        child_positions = @getPositions(false)
-        total_positions = child_positions.length
-
-        selected_x = $selected.offset().left - $start_container.offset().left + (@globals.col_width / 2)
-        selected_y = $selected.offset().top - $start_container.offset().top + ($selected.height() / 2)
-
-        shortest_distance = 9999999
-        target_position = 0
-
-        if total_positions > 1
-          cutoff_start = options.cutoffStart + 1 || 0
-          cutoff_end = options.cutoffEnd || total_positions
-
-          for position_i in [cutoff_start...cutoff_end]
-            attributes = child_positions[position_i]
-
-            if attributes
-              y_dist = selected_x - attributes.left
-              x_dist = selected_y - attributes.top
-
-              if y_dist > 0 and x_dist > 0
-                distance = Math.sqrt((x_dist * x_dist) + (y_dist * y_dist))
-
-                if distance < shortest_distance
-                  shortest_distance = distance
-                  target_position = position_i
-
-                  if position_i is total_positions - 1
-                    if y_dist > parsed_children[position_i].height / 2
-                      target_position++
-
-
-
-          if target_position is parsed_children.length
-            $target = parsed_children[target_position - 1].el
-            $selected.insertAfter($target)
-          else
-            $target = parsed_children[target_position].el
-            $selected.insertBefore($target)
-        else
-          if total_positions is 1
-            attributes = child_positions[0]
-
-            if attributes.left < selected_x
-              @$container.append $selected
-            else
-              @$container.prepend $selected
-          else
-            @$container.append $selected
-
-        @arrange(true)
-
-        if $start_container[0] isnt $selected.parent()[0]
-          previous_container_class = options.previousContainerClass
-          $("." + previous_container_class).trigger "ss-rearrange"
-      else
-        placeholder_class = @options.placeholderClass
-        $("." + placeholder_class).remove()
-
-    # ----------------------------
-    # resize:
-    # Optional feature.
-    # Runs a full render of the elements when
-    # the browser window is resized.
-    # ----------------------------
-    enableResize: ->
-      animation_speed = @options.animationSpeed
-
-      resizing = false
-      binding = "resize." + @identifier
-      $(window).on binding, =>
-        unless resizing
-          resizing = true
-
-          # Some funkyness to prevent too many renderings
-          setTimeout (=> @render()), animation_speed / 3
-          setTimeout (=> @render()), animation_speed / 3
-
-          setTimeout =>
-            resizing = false
-            @render()
-          , animation_speed / 3
-
-    # ----------------------------
-    # lowestCol:
-    # Helper
-    # Returns the index position of the
-    # array column with the lowest number
-    # ----------------------------
-    lowestCol: (array, offset = 0) ->
-      length = array.length
-      augmented_array = []
-
-      for i in [0...length]
-        augmented_array.push [array[i], i]
-
-      augmented_array.sort (a, b) ->
-          ret = a[0] - b[0]
-          ret = a[1] - b[1] if ret is 0
-          ret
-      augmented_array[offset][1]
-
-    # ----------------------------
-    # highestCol:
-    # Helper
-    # Returns the index position of the
-    # array column with the highest number
-    # ----------------------------
-    highestCol: (array) ->
-      $.inArray Math.max.apply(window,array), array
-
-    # ----------------------------
-    # destroy:
-    # ----------------------------
-    destroy: ->
-      $container = @$container
-      $container.off("ss-arrange")
-      $container.off("ss-rearrange")
-      $container.off("ss-setTargetPosition")
-      $container.off("ss-destroy")
-
-      active_class = @options.activeClass
-      $active_children = $container.find("." + active_class)
-
-      if @options.enableDrag
-        $active_children.draggable('destroy')
-      if @options.enableCrossDrop
-        $container.droppable('destroy')
-
-      $active_children.removeClass(active_class)
-      $container.removeClass(@identifier)
-
-
-  $.fn[pluginName] = (options) ->
-    @each ->
-      # Destroy any old resize events
-      old_class = $(@).attr("class").match(/shapeshifted_container_\w+/)?[0]
-      if old_class
-        bound_indentifier = "resize." + old_class
-        $(window).off(bound_indentifier)
-        $(@).removeClass(old_class)
-
-      # Create the new plugin instance
-      $.data(@, "plugin_#{pluginName}", new Plugin(@, options))
-
-)(jQuery, window, document)


hide #hint div by default

hide #hint div by default

--- cf/spell.coffee
+++ cf/spell.coffee
@@ -1,4 +1,5 @@
 $ ->
+  $("#hint").hide()
   words = $.getJSON("spellings.json")
   $.when(words).done ((d)->
     d['words']


Adds more X-MS and X-Yahoo headers to the grammar. Fix a few regex.

--- grammars/eml.cson
+++ grammars/eml.cson
@@ -4,15 +4,15 @@
   'fileTypes': ['eml', 'email', 'mail', 'mime']
   'patterns': [
     # Emails
-    { 'match': '"[a-za-z0-9. \-]+"\s*<[a-za-z0-9.\-]+\@[a-za-z0-9.\-]+>', 'name': 'variable.other.eml' },
-    { 'match': '[a-za-z0-9.\-]*\s*<[a-za-z0-9.\-]+\@[a-za-z0-9.\-]+>', 'name': 'variable.other.eml' },
-    { 'match': '[a-za-z0-9.\-]+\@[a-za-z0-9.\-]+', 'name': 'variable.other.eml' },
+    { 'match': '"[a-zA-Z0-9. \+\_\-]+"\s*<[a-zA-Z0-9.\-]+\@[a-zA-Z0-9.\-]+>', 'name': 'variable.other.eml' },
+    { 'match': '[a-zZ-Z0-9.\+\_\-]*\s*<[a-zA-Z0-9.\-]+\@[a-zA-Z0-9.\-]+>', 'name': 'variable.other.eml' },
+    { 'match': '[a-zA-Z0-9.\+\_\-]+\@[a-zA-Z0-9.\-]+', 'name': 'variable.other.eml' },

-    { 'match': '^(?i)Content-Type: text\/plain;.*?(?=--)', 'name': 'markup.raw.eml' },
-    { 'match': '^(?i)Content-Type: text\/html;.*?(?=--)', 'name': 'markup.raw.eml' },
+    { 'match': '(?i)text\/plain;', 'name': 'markup.raw.eml' },
+    { 'match': '(?i)text\/html;', 'name': 'markup.raw.eml' },

     # Separator
-    { 'match': '^.*(?i)boundary\=.*__.*__"', 'name': 'keyword.control' },
+    { 'match': '\sboundary\=.*?', 'name': 'keyword.control' },
     { 'match': '^--.*', 'name': 'keyword.control' },

     { 'match': '^.*(?i)authentication-results.*?:', 'name': 'constant.language.eml' },
@@ -20,28 +20,35 @@
     { 'match': '^.*(?i)cc.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)comments.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)content-disposition.*?:', 'name': 'constant.language.eml' },
+    { 'match': '^.*(?i)content-language.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)content-transfer-encoding.*?:', 'name': 'constant.language.eml' },
-    { 'match': '^(?i)content-type.*?:', 'name': 'constant.language.eml' },
-    { 'match': '^.*(?i)date.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)delivered-to.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)delivery-date.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)dkim-signature.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)domainkey-signature.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)envelope-from.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)enverlope-to.*?:', 'name': 'constant.language.eml' },
-    { 'match': '^(?i)from.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)in-reply-to.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)keywors.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)list-help.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)list-post.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)list-unsubscribe.*?:', 'name': 'constant.language.eml' },
-    { 'match': '^.*(?i)message-id.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)mime-version.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)precedence.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)received-spf.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)received.*?:', 'name': 'constant.language.eml' }
     { 'match': '^.*(?i)references.*?:', 'name': 'constant.language.eml' },
     { 'match': '^.*(?i)reply-to.*?:', 'name': 'constant.language.eml' },
+    { 'match': '^(?i)content-type.*?:', 'name': 'constant.language.eml' },
+    { 'match': '^(?i)date.*?:', 'name': 'constant.language.eml' },
+    { 'match': '^(?i)from.*?:', 'name': 'constant.language.eml' },
+    { 'match': '^(?i)message-id.*?:', 'name': 'constant.language.eml' },
+    { 'match': '^(?i)return-path.*?:', 'name': 'constant.language.eml' },
+    { 'match': '^(?i)sender.*?:', 'name': 'constant.language.eml' },
+    { 'match': '^(?i)subject.*?:', 'name': 'constant.language.eml' },
+    { 'match': '^(?i)thread-index.*?:', 'name': 'constant.language.eml' },
+    { 'match': '^(?i)thread-topic.*?:', 'name': 'constant.language.eml' },
+    { 'match': '^(?i)to.*?:', 'name': 'constant.language.eml' },

     # Resent Headers
     { 'match': '^.*(?i)resent-bcc.*?:', 'name': 'constant.other.eml' },
@@ -53,35 +60,51 @@
     { 'match': '^.*(?i)resent-sender.*?:', 'name': 'constant.other.eml' },
     { 'match': '^.*(?i)resent-to.*?:', 'name': 'constant.other.eml' },

-    { 'match': '^.*(?i)return-path.*?:', 'name': 'constant.language.eml' },
-    { 'match': '^.*(?i)sender.*?:', 'name': 'constant.language.eml' },
-    { 'match': '^.*(?i)subject.*?:', 'name': 'constant.language.eml' },
-    { 'match': '^.*(?i)to.*?:', 'name': 'constant.language.eml' },
-
     # X-Headers
     { 'match': '^.*(?i)x-bulkmail.*?:', 'name': 'constant.other.eml' },
-    { 'match': '^.*(?i)x-cmae-analysis.*?', 'name': 'constant.other.eml' },
-    { 'match': '^.*(?i)x-cmae-score.*?', 'name': 'constant.other.eml' },
-    { 'match': '^.*(?i)x-gm-message-state.*?', 'name': 'constant.other.eml' },
-    { 'match': '^.*(?i)x-google-dkim-signature.*?', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-cmae-analysis.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-cmae-score.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-eopattributedmessage.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-exchange-antispam-report-cfa-test.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-forefront-antispam-report.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-forefront-prvs.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-gm-message-state.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-google-dkim-signature.*?:', 'name': 'constant.other.eml' },
     { 'match': '^.*(?i)x-loop.*?:', 'name': 'constant.other.eml' },
     { 'match': '^.*(?i)x-mailgun-sid.*?:', 'name': 'constant.other.eml' },
     { 'match': '^.*(?i)x-mailing-list.*?:', 'name': 'constant.other.eml' },
     { 'match': '^.*(?i)x-mc-unique.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-microsoft-antispam.*?:', 'name': 'constant.other.eml' },
     { 'match': '^.*(?i)x-mozilla-status.*?:', 'name': 'constant.other.eml' },
     { 'match': '^.*(?i)x-mozilla-status2.*?:', 'name': 'constant.other.eml' },
-    { 'match': '^.*(?i)x-original-to.*?', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-ms-exchange-crosstenant-fromentityheader.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-ms-exchange-crosstenant-id.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-ms-exchange-crosstenant-originalarrivaltime.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-ms-exchange-messagesentrepresentingtype.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-ms-exchange-transport-crosstenantheadersstamped.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-ms-has-attach.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-ms-office365-filtering-correlation-id.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-ms-tnef-correlator.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-original-to.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-originalarrivaltime.*?:', 'name': 'constant.other.eml' },
     { 'match': '^.*(?i)x-originating-email.*?:', 'name': 'constant.other.eml' },
     { 'match': '^.*(?i)x-originating-ip.*?:', 'name': 'constant.other.eml' },
-    { 'match': '^.*(?i)x-received.*?', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-originatororg.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-received.*?:', 'name': 'constant.other.eml' },
     { 'match': '^.*(?i)x-sender.*?:', 'name': 'constant.other.eml' },
-    { 'match': '^.*(?i)x-spam-checker-version.*?', 'name': 'constant.other.eml' },
-    { 'match': '^.*(?i)x-spam-level.*?', 'name': 'constant.other.eml' },
-    { 'match': '^.*(?i)x-spam-status.*?', 'name': 'constant.other.eml' },
-    { 'match': '^.*(?i)x-spam-zendesk-report.*?', 'name': 'constant.other.eml' },
-    { 'match': '^.*(?i)x-spam-zendesk-score.*?', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-spam-checker-version.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-spam-level.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-spam-status.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-spam-zendesk-report.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-spam-zendesk-score.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-tmn.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-yahoo-newman-id.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-yahoo-newman-property.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-ymail-isg.*?:', 'name': 'constant.other.eml' },
+    { 'match': '^.*(?i)x-ymail-osg.*?:', 'name': 'constant.other.eml' },

     { 'match': '^(-)?--(--.*)?', 'name': 'comment.line.eml' },
+    { 'match': '^\s\*.*', 'name': 'comment.line.eml' },
     { 'match': '^[|>]*[\s_-]*[_-][_-][\s_-]*$">-', 'name': 'sign' },

     # Quoted Text
@@ -92,7 +115,7 @@
     { 'match': '^[|>]\s*[|>]\s*[|>]\s*[|>]\s*[|>].*', 'name': 'indent5' },
     { 'match': '^[|>]\s*[|>]\s*[|>]\s*[|>]\s*[|>]\s*[|>].*', 'name': 'indent6' },

-    { 'match': '^[a-za-z0-9+=]+=$', 'name': 'string.unquoted' },
+    { 'match': '^[a-zA-Z0-9+=]+=$', 'name': 'string.unquoted' },

     # UTF-8
     { 'match': '=\d\d', 'name': 'string.other' }


Add "then" to Pic keywords

Add "then" to Pic keywords

--- grammars/pic.cson
+++ grammars/pic.cson
@@ -87,7 +87,7 @@
 	# Keywords
 	keywords:
 		name: "keyword.operator.$1.pic"
-		match: "\\b(and|at|from|reset|to|with|of\\s+the\\s+way\\s+between)\\b"
+		match: "\\b(and|at|from|reset|then|to|with|of\\s+the\\s+way\\s+between)\\b"

 	# Primitives


cleaned up messages in profiling functions

--- src/Toolbox.coffee
+++ src/Toolbox.coffee
@@ -62,7 +62,8 @@
     # only logging if thresholds are ok, otherwise simply returning
     return ret if loglevel > Observatory.settings.profiling.maxProfilingLevel

-    msg = "#{options.method} call finished in #{t2} ms | #{options.message}"
+    options.message = if options.message? then "| #{options.message}" else ''
+    msg = "#{options.method} call finished in #{t2} ms #{options.message}"
     object =
       timeElapsed: t2
       method: options.method
@@ -95,7 +96,8 @@
       loglevel = @_determineProfilingLevel t2
       # only logging if thresholds are ok, otherwise simply returning
       if loglevel < Observatory.settings.profiling.maxProfilingLevel
-        msg = "#{options.method} call finished in #{t2} ms | #{options.message}"
+        options.message = if options.message? then "| #{options.message}" else ''
+        msg = "#{options.method} call finished in #{t2} ms #{options.message}"
         object =
           timeElapsed: t2
           method: options.method


extended profiling message format to support subscriptions

--- src/Toolbox.coffee
+++ src/Toolbox.coffee
@@ -64,8 +64,10 @@
         timeElapsed: timeElapsed
         method: options.method
         arguments: JSON.stringify args
-        stack: (new Error()).stack
-        type: "profile.end"
+        #stack: (new Error()).stack
+        type: options.profileType ? "profile.end"
+    _.extend opts.obj, options.obj
+    opts

   # TODO: write tests for profiling functions
   # profile sync function execution


Tweak saving and how each ckeditor.dirty is reset

--- app/assets/javascripts/effective_ckeditor/init.js.coffee
+++ app/assets/javascripts/effective_ckeditor/init.js.coffee
@@ -73,7 +73,8 @@
     templates_replaceContent: false
     filebrowserWindowHeight: 600
     filebrowserWindowWidth: 800
-    filebrowserBrowseUrl: '/effective/assets?only=images'
+    filebrowserBrowseUrl: '/effective/assets'
+    filebrowserImageBrowseUrl: '/effective/assets?only=images'
     referencesEditorSelector:"'#' + editor.name"
     toolbar_full: [
       { name: 'save', items: ['Save', '-', 'NewPage'] },


allow propagation

allow propagation

--- app/assets/javascripts/floating_formato_helper.js.coffee
+++ app/assets/javascripts/floating_formato_helper.js.coffee
@@ -6,7 +6,7 @@
       $form = $("form")
       url = $form.attr "action"
       $.post "#{url}/validate", $form.serialize(), "script"
-      false
+      true

     $(document).on "nested:fieldRemoved", ->
       # let's trigger upon fields removal


Clear box before showing comments for anchor

--- app/assets/javascripts/legislation_annotatable.js.coffee
+++ app/assets/javascripts/legislation_annotatable.js.coffee
@@ -141,6 +141,7 @@
           if $("span[data-annotation-id='" + ann_id + "']").length
             el = $("span[data-annotation-id='" + ann_id + "']")
             el.addClass('current-annotation')
+            $('#comments-box').html('')
             App.LegislationAllegations.show_comments()
             $('html,body').animate({scrollTop: el.offset().top})
             $.event.trigger


add getRecoveredTime test

add getRecoveredTime test

--- test/test_stamina-calculator.coffee
+++ test/test_stamina-calculator.coffee
@@ -78,3 +78,13 @@
       next_levelup_clear_times = Math.ceil(@stamina_calculator.getNextLevelupTimes(1, 86))
       expect(next_levelup_clear_times).to.eql(1)
       done()
+
+  describe 'getRecoveredTime', ->
+    beforeEach (done) ->
+      @stamina_calculator = new StaminaCalculator @stamina_recovery_time
+      done()
+
+    it.skip 'correct data', (done)->
+      recover_time = @stamina_calculator.getRecoveredTime(125)
+      expect(recover_time).to.eql(125 * @stamina_recovery_time)
+      done()


EDSC-148: Fix granule layer disposal issues

--- app/assets/javascripts/models/ui/datasets_list.js.coffee
+++ app/assets/javascripts/models/ui/datasets_list.js.coffee
@@ -46,7 +46,6 @@

     unfocusDataset: =>
       if @focused()?
-        @focused().dispose()
         setTimeout((=> @focused(null)), 400)

     _readFocused: ->


Added tests for the AWS.QueryService parseResponse method.

--- test/unit/query_service.spec.coffee
+++ test/unit/query_service.spec.coffee
@@ -13,7 +13,8 @@
     operations:
       simpleMethod:
         n: 'OperationName'
-        i: { Input:{} }
+        i: {Input:{}}
+        o: {Data:{t:'o',m:{Name:{t:'s'},Count:{t:'i'}}}}

   AWS.Service.defineMethods(MockQueryService)

@@ -45,6 +46,24 @@
     it 'should uri encode params properly', ->
       expect(req.params.toString()).toMatch(/foo%2Bbar%3A%20yuck%2Fbaz%3D~/);

+  describe 'parseResponse', ->
+
+    httpResponse = new AWS.HttpResponse()
+    httpResponse.status = 200
+    httpResponse.headers = {}
+    httpResponse.body = """
+      <xml>
+        <Data>
+          <Name>abc</Name>
+          <Count>123</Count>
+        </Data>
+      </xml>
+    """
+
+    it 'parses the response using the operation output rules', ->
+      data = svc.parseResponse(httpResponse, 'simpleMethod')
+      expect(data).toEqual({Data:{Name:'abc',Count:123}})
+
   describe 'extractError', ->

     httpResponse = new AWS.HttpResponse()


respond == hear in the context of an SMS

`respond` and `hear` are different things for multi-user backends, but SMS
is single-user.

In single-user backends, the receipt of a message is enough to verify
that it was addressed to the bot.

--- src/hubot/twilio.coffee
+++ src/hubot/twilio.coffee
@@ -22,6 +22,9 @@
   reply: (user, strings...) ->
     strings.forEach (str) =>
       @send user, "#{user.name}: #{str}"
+
+  respond: (regex, callback) ->
+    @hear regex, callback

   run: ->
     console.log "Hubot: the SMS reader."


removing log statements

removing log statements

--- app/assets/coffee/apps/episodes/playlist/playlist_controller.coffee
+++ app/assets/coffee/apps/episodes/playlist/playlist_controller.coffee
@@ -10,7 +10,6 @@
           fetchingPlaylist = Swabcast.request("entities:playlist")
           playlistLayout = new View.Layout()
           $.when(fetchingPlaylist).done (tracks) ->
-            console.log(tracks)
             self = this
             emptyView = undefined

@@ -59,7 +58,7 @@
                     newTrack.save()
                     Swabcast.commands.execute "player:setepisode", newTrack.get("id")  if tracks.at(0) is newTrack
                     #update the playlist in mainview
-                    Playlist.trigger "playlist:newepisode", newTrack
+                    # Playlist.trigger "playlist:newepisode", newTrack
                     tracks.nowPlaying = newTrack  unless tracks.nowPlaying
                 else
                   if apiResponse == "fail"
@@ -85,7 +84,6 @@
           mainPlaylistLayout = new View.ManagePlaylistLayout()

           mainPlaylistLayout.on "show", ->
-            console.log(localStorage)
             fetchingPlaylist = Swabcast.request("entities:playlist")

             $.when(fetchingPlaylist).done (episodes) ->
@@ -104,13 +102,11 @@
                 model.destroy()

               playlistEpisodes.listenTo Playlist, "playlist:newepisode", (model) ->
-                console.log("showManagePlaylist", model)
                 episodes.add newTrack
                 newTrack.save()
                 playlistEpisodes.render()

               playlistEpisodes.on "playlist:update", (childView, model) ->
-                console.log("playlist:update")
                 playlistEpisodes.children.findByModel(model).flash "success"

               Swabcast.sideBarRegion.close()


select2bridge with conditions data attr

select2bridge with conditions data attr

--- app/assets/javascripts/ab_admin/components/select2_bridge.js.coffee
+++ app/assets/javascripts/ab_admin/components/select2_bridge.js.coffee
@@ -143,26 +143,27 @@

   fetchAjaxParams: (term, page) =>
     cond = {}
-    if @el.data('c')
+    condData = JSON.parse(@el.attr('data-c') || null)
+    if condData
       for kind in ['with', 'without']
-        if @el.data('c')[kind]
+        if condData[kind]
           cond[kind] ||= {}
-          for attr, id of @el.data('c')[kind]
+          for attr, id of condData[kind]
             value = $('#' + id).val()
             cond[kind][attr] = value if value

       for kind in ['with_term', 'without_term']
-        if @el.data('c')[kind]
+        if condData[kind]
           kind_key = kind.replace(/_term$/, '')
           cond[kind_key] ||= {}
-          for attr, value of @el.data('c')[kind]
+          for attr, value of condData[kind]
             cond[kind_key][attr] = value if value

       for kind in ['with_selector', 'without_selector']
-        if @el.data('c')[kind]
+        if condData[kind]
           kind_key = kind.replace(/_selector$/, '')
           cond[kind_key] ||= {}
-          for attr, value of @el.data('c')[kind]
+          for attr, value of condData[kind]
             selectors = value.split(/\s+/)
             value = @el.closest(selectors[1] || 'html').find(selectors[0]).val()
             cond[kind_key][attr] = value if value


cleanup

cleanup

--- app/assets/javascripts/ab_admin/components/select2_bridge.js.coffee
+++ app/assets/javascripts/ab_admin/components/select2_bridge.js.coffee
@@ -148,11 +148,3 @@

     data = {q: term, class: @el.data('class'), token: true, page: page}
     _.extend(data, cond)
-
-
-#    $('#district_location_id').select2("data", {id: 123, text: '123'})
-#    $el.change (data) ->
-#      log data.val
-#    createSearchChoice: (term) ->
-#      log term
-#      {id: 3, text: '123'}


The Collection instantiates the correct type of model.

--- app/assets/javascripts/models/assignment.js.coffee
+++ app/assets/javascripts/models/assignment.js.coffee
@@ -1,14 +1,11 @@
 class window.StaffPlan.Models.Assignment extends StaffPlan.Model
   NAME: "assignment"
   initialize: ->
-    weeks = _.map @get("work_weeks"), (week) ->
-      new StaffPlan.Models.WorkWeek week
-    @work_weeks = new StaffPlan.Collections.WorkWeeks weeks,
+    @work_weeks = new StaffPlan.Collections.WorkWeeks @get("work_weeks"),
       parent: @
+    @unset "work_weeks"

     @work_weeks.sort()
-    # No need for this anymore
-    @unset "work_weeks"

     # When an element is removed from a collection, a "remove" event is triggered
     @bind 'remove', () ->


fullpieagent testing

fullpieagent testing

--- widgets/fullpie_agent/fullpie_agent.coffee
+++ widgets/fullpie_agent/fullpie_agent.coffee
@@ -239,10 +239,11 @@
             .remove()

         labelLayout = d3.geom.quadtree()
-            .extent([[-width,-height], [width,height] ])
+            .extent([[-width,-height], [width,height] ])([])
+        labelLayout
             .x((d) -> return d.x)
             .y((d) -> return d.y)
-            ([]) #create an empty quadtree to hold label positions
+#            ([]) #create an empty quadtree to hold label positions
         maxLabelWidth = 0
         maxLabelHeight = 0


Agent pie: start/end angle pie transition work

--- widgets/fullpie_agent/fullpie_agent.coffee
+++ widgets/fullpie_agent/fullpie_agent.coffee
@@ -4,13 +4,24 @@

     #constructor: ->
     ready: ->
+        #@testData = 123
+        #@oldPieData = ''
         @instanceDataId = $(@node).attr('data-id')
+        #console.log('@instanceDataId',@instanceDataId)
+        #@oldPieData[@instanceDataId] = ''
         window.oldPieData = window.oldPieData or {}
         window.oldPieData[@instanceDataId] = window.oldPieData[@instanceDataId] or []

     onData: (data) ->
+        #console.log('testData',@testData)
+        #@testData = @testData + 1
+        #console.log('testData',@testData)
+        #console.log('window.oldPieData',window.oldPieData)
+
         #$(@node).fadeOut().fadeIn()
         @container = $(@node).parent()
+        #@instanceDataId = $(@node).attr('data-id')
+        #console.log('@instanceDataId',@instanceDataId)

         #
         # CONFIG ZONE
@@ -395,5 +406,6 @@
         window.oldPieData = window.oldPieData or {}
         window.oldPieData[@instanceDataId] = window.oldPieData[@instanceDataId] or []
         window.oldPieData[@instanceDataId] = piedata
-        console.log('piedata',piedata)
+        #console.log('piedata',piedata)
+        console.log('EOF: window.oldPieData[@instanceDataId]',window.oldPieData[@instanceDataId])
         return


--- widgets/fullpie_agent/fullpie_agent.coffee
+++ widgets/fullpie_agent/fullpie_agent.coffee
@@ -206,8 +206,12 @@
             #    return arc b
         #)
         path.transition().duration(2000).attrTween('d', (d) ->
+            console.log('1. in tween - window.oldPieData[myInstanceDataId]: ',window.oldPieData[myInstanceDataId])
+            console.log('1. in tween - d: ',d)
             myInterpolater = d3.interpolate(window.oldPieData[myInstanceDataId], d)
             window.oldPieData[myInstanceDataId] = myInterpolater(0)
+            console.log('2. in tween - window.oldPieData[myInstanceDataId]: ',window.oldPieData[myInstanceDataId])
+            console.log('2. in tween - d: ',d)
             return (t) ->
                 return arc(myInterpolater(t))
         )


update.

update.

--- src/main/public/nz/SpriteCharacter.coffee
+++ src/main/public/nz/SpriteCharacter.coffee
@@ -63,8 +63,12 @@
       @_hitBallet(e.owner,e.ballet)
       return
     @on 'deadCharacter', (e) ->
+      {
+        character
+      } = e
       # TODO:アニメーション
-      @hide()
+      if e.character is @character
+        @hide()
       return
     return

@@ -313,6 +317,7 @@
     @character.hp -= d
     h = @getRoot().eventHandler
     h.refreshStatus()
+    console.log "#{@character.name} damage #{d} hp #{@character.hp}"
     if @character.hp <= 0
       h.deadCharacter(@character)
     return


searching gremlins from document

searching gremlins from document

--- app/scripts/gremlin/domObserver/ElementList.coffee
+++ app/scripts/gremlin/domObserver/ElementList.coffee
@@ -1,16 +1,17 @@
 goog.provide 'gremlin.domObserver.ElementList'
+
 goog.require 'gremlin.util.FeatureDetector'
 goog.require 'gremlin.gremlins.NameProvider'

 class gremlin.domObserver.ElementList
   class NativeQuerySelector
     @get: (attributeName) ->
-      elements = document.body.querySelectorAll "[#{gremlin.gremlins.NameProvider.DATA_NAME_ATTR}]"
+      elements = document.querySelectorAll "[#{gremlin.gremlins.NameProvider.DATA_NAME_ATTR}]"
       (element for element in elements)

   class LegacySelector
     @get: (attributeName) ->
-      elements = document.body.getElementsByTagName '*'
+      elements = document.getElementsByTagName '*'
       (element for element in elements when gremlin.gremlins.NameProvider.isGremlin(element))

   isNative = gremlin.util.FeatureDetector.hasQuerySelectorAll


fullpieagent testing

fullpieagent testing

--- widgets/fullpie_agent/fullpie_agent.coffee
+++ widgets/fullpie_agent/fullpie_agent.coffee
@@ -280,7 +280,7 @@
             # check whether the default position
             #   overlaps any other labels
             conflicts = []
-            labelLayout.visit((node, x1, y1, x2, y2) ->
+            labelLayout.visit( (node, x1, y1, x2, y2) ->
                 #recurse down the tree, adding any overlapping
                 #node is the node in the quadtree,
                 #node.point is the value that we added to the tree
@@ -291,16 +291,16 @@
                 #2. right edge of node is to the left of left edge of label
                 #3. top (minY) edge of node is greater than the bottom of label
                 #4. bottom (maxY) edge of node is less than the top of label
-                if  (x1 > d.r + maxLabelWidth/2) ||(x2 < d.l - maxLabelWidth/2) ||(y1 > d.b + maxLabelHeight/2) || (y2 < d.t - maxLabelHeight/2 )
+                if  (x1 > d.r + maxLabelWidth/2) or (x2 < d.l - maxLabelWidth/2) or (y1 > d.b + maxLabelHeight/2) or (y2 < d.t - maxLabelHeight/2 )
                     return true #don't bother visiting children or checking this node

                 p = node.point
                 v = false
                 h = false
                 if p #p is defined, i.e., there is a value stored in this node
-                    h =  ( ((p.l > d.l) && (p.l <= d.r)) || ((p.r > d.l) && (p.r <= d.r)) || ((p.l < d.l)&&(p.r >=d.r) ) ) #horizontal conflict
-                    v =  ( ((p.t > d.t) && (p.t <= d.b)) || ((p.b > d.t) && (p.b <= d.b)) || ((p.t < d.t)&&(p.b >=d.b) ) ) #vertical conflict
-                    if h && v
+                    h =  ( ((p.l > d.l) and (p.l <= d.r)) or ((p.r > d.l) and (p.r <= d.r)) or ((p.l < d.l) and (p.r >=d.r) ) ) #horizontal conflict
+                    v =  ( ((p.t > d.t) and (p.t <= d.b)) or ((p.b > d.t) and (p.b <= d.b)) or ((p.t < d.t) and (p.b >=d.b) ) ) #vertical conflict
+                    if h and v
                         conflicts.push(p) #add to conflict list
             )


focus editor, duh

focus editor, duh

--- HTML/lib/atomicity.coffee
+++ HTML/lib/atomicity.coffee
@@ -8,6 +8,7 @@
 editor.getSession().setMode new JavaScriptMode
 editor.getSession().setUseSoftTabs true
 editor.getSession().setTabSize 2
+editor.focus()

 if css = File.read "~/.atomicity/twilight.css"
   head = $('head')[0]


JVM: Add stack information to vms

JVM: Add stack information to vms

--- workers/social/lib/social/models/vm.coffee
+++ workers/social/lib/social/models/vm.coffee
@@ -8,7 +8,7 @@
 module.exports = class JVM extends Module

   {permit} = require './group/permissionset'
-  {secure, dash, signature} = require 'bongo'
+  {ObjectId, secure, dash, signature} = require 'bongo'
   {uniq}   = require 'underscore'

   {argv} = require 'optimist'
@@ -128,6 +128,7 @@
       numCPUs           :
         type            : Number
         default         : KONFIG.defaultVMConfigs.freeVM.cpu ? 1
+      stack             : ObjectId

   suspend: (callback)->
     @update { $set: { hostKite: '(banned)' } }, (err)=>
@@ -188,7 +189,7 @@
         return callback err if err
         callback null, vm.hostnameAlias

-  @createDomains = (account, domains, hostnameAlias)->
+  @createDomains = ({account, domains, hostnameAlias, stack})->

     updateRelationship = (domainObj)->
       Relationship.one
@@ -210,6 +211,7 @@
         proxy         : { mode: 'vm' }
         regYears      : 0
         loadBalancer  : { persistance: 'disabled' }
+        stack         : stack
       domainObj.save (err)->
         if err
         then console.error err  unless err.code is 11000
@@ -241,7 +243,7 @@
                   @ensureDomainSettings {account, vm, type, nickname, groupSlug}
                   @createDomains account, hostnameAliases, hostnameAliases[0]

-  @ensureDomainSettings = ({account, vm, type, nickname, groupSlug})->
+  @ensureDomainSettings = ({account, vm, type, nickname, groupSlug, stack})->
     domain = 'kd.io'
     if type in ['user', 'expensed']
       requiredDomains = ["#{nickname}.#{groupSlug}.#{domain}"]
@@ -249,7 +251,9 @@
         requiredDomains.push "#{nickname}.#{domain}"
     else
       requiredDomains = ["#{groupSlug}.#{domain}", "shared.#{groupSlug}.#{domain}"]
-    @createDomains account, requiredDomains, vm.hostnameAlias
+
+    {hostnameAlias} = vm
+    @createDomains {account, domains:requiredDomains, hostnameAlias, stack}

   @createAliases = ({nickname, type, uid, groupSlug})->
     domain       = 'kd.io'
@@ -329,6 +333,7 @@
                 planOwner : "user_#{account._id}"
                 webHome   : account.profile.nickname
                 groups    : wrapGroup group
+                # ADD HERE ------------
               }, callback

       else
@@ -392,6 +397,7 @@
   # discussion between Devrim, Chris T. and Badahir  C.T.
   @createVm = ({account, type, groupSlug, planCode, subscriptionCode}, callback)->
     JGroup = require './group'
+    JStack = require './stack'
     JGroup.one {slug: groupSlug}, (err, group)=>
       return callback err  if err
       return callback new Error "Group not found"  unless group
@@ -421,32 +427,39 @@
           groups        = [{ id: group.getId() }]
           hostnameAlias = hostnameAliases[0]

-          vm = new JVM {
-            hostnameAlias
-            planCode
-            subscriptionCode
-            webHome
-            groups
-            users
-            vmType: type
-          }
-
-          vm.save (err) =>
-
-            if err
-              return console.warn "Failed to create VM for ", \
-                                   {users, groups, hostnameAlias}
-
-            JVM.createDomains account, hostnameAliases, hostnameAliases[0]
-
-            group.addVm vm, (err)=>
-              return callback err  if err
-              JVM.ensureDomainSettings {account, vm, type, nickname, groupSlug}
-              if type is 'group'
-                @addVmUsers user, vm, group, ->
+          JStack.getStackId {user: nickname, group: groupSlug}, (err, stack)=>
+
+            vm = new JVM {
+              hostnameAlias
+              planCode
+              subscriptionCode
+              webHome
+              groups
+              users
+              vmType : type
+              stack
+            }
+
+            vm.save (err) =>
+
+              if err
+                return console.warn "Failed to create VM for ", \
+                                     {users, groups, hostnameAlias}
+
+              JVM.createDomains {
+                account, stack,
+                domains:hostnameAliases
+                hostnameAlias:hostnameAliases[0]
+              }
+
+              group.addVm vm, (err)=>
+                return callback err  if err
+                JVM.ensureDomainSettings {account, vm, type, nickname, groupSlug, stack}
+                if type is 'group'
+                  @addVmUsers user, vm, group, ->
+                    callback null, vm
+                else
                   callback null, vm
-              else
-                callback null, vm

   @addVmUsers = (user, vm, group, callback)->
     # todo - do this operation in batches
@@ -532,13 +545,17 @@
       return callback new Error "user not found" unless user

       selector.users = $elemMatch: id: user.getId()
-
-      JVM.someData selector, { hostnameAlias: 1 }, options, (err, cursor)->
+      fieldsToFetch = { hostnameAlias: 1, stack: 1 }
+      JVM.someData selector, fieldsToFetch, options, (err, cursor)->
         return callback err  if err

         cursor.toArray (err, arr)->
           return callback err  if err
-          callback null, arr.map (vm)-> vm.hostnameAlias
+          if options.withStacks
+            callback null, arr.map (vm)->
+              {alias:vm.hostnameAlias, stack:vm.stack}
+          else
+            callback null, arr.map (vm)-> vm.hostnameAlias

   @fetchVmsByContext = secure (client, options, callback) ->
     {connection:{delegate}, context:{group}} = client
@@ -671,7 +688,7 @@
         callback err, vm

   @addVm = ({ account, target, user, sudo, groups, groupSlug
-             type, planCode, planOwner, webHome, uid }, callback)->
+             type, planCode, planOwner, webHome, uid, stack }, callback)->

     return handleError new Error "user is not defined"  unless user
     nickname = account.profile.nickname or user.username
@@ -696,6 +713,7 @@
       groups
       users
       vmType: type
+      stack
     }

     vm.save (err)->
@@ -708,8 +726,9 @@
                              {users, groups, hostnameAlias}

       JVM.ensureDomainSettings \
-        {account, vm, type, nickname, groupSlug}
-      JVM.createDomains account, hostnameAliases, hostnameAlias
+        {account, vm, type, nickname, groupSlug, stack}
+      JVM.createDomains \
+        {account, domains:hostnameAliases, hostnameAlias, stack}
       target.addVm vm, handleError

   wrapGroup = (group)-> [ { id: group.getId() } ]
@@ -791,27 +810,45 @@
             return console.error err  if err or not account
             # New account found
             webHome       = username
-            vm.update {$set: {hostnameAlias:newHostNameAlias, webHome}},(err)=>
-
-              return console.error err  if err
-              # VM hostnameAlias updated
-
-              nameFactory = (require 'koding-counter')
-                db          : JVM.getClient()
-                offset      : 0
-                counterName : "koding~#{username}~"
-              nameFactory.next (err, uid)=>
+
+            JStack = require './stack'
+            JStack.getStackId {user:username, group}, (err, stack)=>
+
+              if err then warn "Failed to get stack:", err
+
+              stack ?= null
+              vm.update
+                $set: {
+                  webHome, stack,
+                  hostnameAlias: newHostNameAlias
+                }
+              , (err)=>
+
                 return console.error err  if err
-                # Counter created
-
-                hostnameAliases = JVM.createAliases {
-                  nickname:username
-                  type:'user', uid, groupSlug:'koding'
-                }
-                JVM.createDomains account, hostnameAliases, hostnameAliases[0]
-
-                console.log """Migration completed for
-                               #{hostnameAlias} to #{newHostNameAlias}"""
+                # VM hostnameAlias updated
+
+                nameFactory = (require 'koding-counter')
+                  db          : JVM.getClient()
+                  offset      : 0
+                  counterName : "koding~#{username}~"
+
+                nameFactory.next (err, uid)=>
+                  return console.error err  if err
+                  # Counter created
+
+                  hostnameAliases = JVM.createAliases {
+                    nickname:username
+                    type:'user', uid, groupSlug:'koding'
+                  }
+
+                  JVM.createDomains {
+                    account, stack,
+                    domains:hostnameAliases,
+                    hostnameAlias:hostnameAliases[0]
+                  }
+
+                  console.log """Migration completed for
+                                 #{hostnameAlias} to #{newHostNameAlias}"""

     JGroup.on 'GroupDestroyed', (group)->
       group.fetchVms (err, vms)->


MainNav: Teamwork and about added to navbar

--- client/Main/maincontroller/dockcontroller.coffee
+++ client/Main/maincontroller/dockcontroller.coffee
@@ -6,8 +6,8 @@
     { title : "Terminal",  path : "/Terminal", order : 30, type :"" }
     { title : "Editor",    path : "/Ace",      order : 40, type :"" }
     { title : "Apps",      path : "/Apps",     order : 50, type :"" }
-    # { title : "Finder",    path : "/Finder",   order : 60, type :"" }
-    # { title : "About",     path : "/About",    order : 70, type :"" }
+    { title : "Teamwork",  path : "/Teamwork", order : 60, type :"" }
+    { title : "About",     path : "/About",    order : 70, type :"" }
   ]

   createHash = (arr)->


Dock: changed teamwork's order

Dock: changed teamwork's order

--- client/Main/maincontroller/dockcontroller.coffee
+++ client/Main/maincontroller/dockcontroller.coffee
@@ -2,11 +2,11 @@

   defaultItems = [
     { title : "Activity",  path : "/Activity", order : 10, type :"" }
-    { title : "Topics",    path : "/Topics",   order : 20, type :"" }
+    # { title : "Topics",    path : "/Topics",   order : 20, type :"" }
+    { title : "Teamwork",  path : "/Teamwork", order : 20, type :"" }
     { title : "Terminal",  path : "/Terminal", order : 30, type :"" }
     { title : "Editor",    path : "/Ace",      order : 40, type :"" }
     { title : "Apps",      path : "/Apps",     order : 50, type :"" }
-    { title : "Teamwork",  path : "/Teamwork", order : 60, type :"" }
     # { title : "About",     path : "/About",    order : 70, type :"" }
   ]


Main: couldnt connect to backend modal width fixed

--- client/Main/maincontroller/maincontroller.coffee
+++ client/Main/maincontroller/maincontroller.coffee
@@ -160,9 +160,9 @@
     { JUser } = KD.remote.api

     @isLoggingIn on
-
+
     credentials.username = credentials.username.toLowerCase().trim()
-
+
     JUser.login credentials, (err, result) =>
       return callback err  if err
       @swapAccount result, callback
@@ -221,6 +221,7 @@
                      We don't know why, but your browser couldn't reach our server.

Please try again.

"
         height  : "auto"
+        width   : 600
         overlay : yes
         buttons :
           "Refresh Now" :


MainController: minor cleanup

MainController: minor cleanup

--- client/Main/maincontroller/maincontroller.coffee
+++ client/Main/maincontroller/maincontroller.coffee
@@ -41,7 +41,7 @@
     KD.registerSingleton "linkController",            new LinkController
     KD.registerSingleton "display",                   new ContentDisplayController
     KD.registerSingleton "kiteController",            new KiteController
-    KD.registerSingleton 'router',           router = new KodingRouter
+    KD.registerSingleton 'router',                    new KodingRouter
     KD.registerSingleton "localStorageController",    new LocalStorageController
     KD.registerSingleton "oauthController",           new OAuthController
     KD.registerSingleton "groupsController",          new GroupsController
@@ -228,16 +228,6 @@
     else
       @_isLoggingIn ? no

-  showInstructionsBook:->
-    if Cookies.get 'newRegister'
-      @emit "ShowInstructionsBook", 9
-      Cookies.expire 'newRegister'
-    else if @isUserLoggedIn()
-      BookView::getNewPages (pages)=>
-        return unless pages.length
-        BookView.navigateNewPages = yes
-        @emit "ShowInstructionsBook", pages.first.index
-
   setFailTimer: do->
     notification = null
     fail  = ->