add the missing style for the file input

error: pathspec 'app/assets/javascripts/locomotive/views/inputs/file_view.js.coffee' did not match any file(s) known to git

--- app/assets/javascripts/locomotive/views/inputs/file_view.js.coffee
+++ app/assets/javascripts/locomotive/views/inputs/file_view.js.coffee
@@ -0,0 +1,182 @@
+Locomotive.Views.Inputs ||= {}
+
+class Locomotive.Views.Inputs.FileView extends Backbone.View
+
+  events:
+    'change input[type=file]':  'change_file'
+    'click a.choose':           'begin_choose_file'
+    'click a.change':           'begin_change_file'
+    'click a.cancel':           'cancel_new_file'
+    'click a.delete':           'mark_file_as_deleted'
+
+  initialize: ->
+    @$file          = @$('input[type=file]')
+    @$remove_file   = @$('input[type=hidden]')
+    @$current_file  = @$('.current-file')
+    @$no_file       = @$('.no-file')
+    @$new_file      = @$('.new-file')
+
+    @$choose_btn    = @$('.buttons .choose')
+    @$change_btn    = @$('.buttons .change')
+    @$cancel_btn    = @$('.buttons .cancel')
+    @$delete_btn    = @$('.buttons .delete')
+
+    @persisted_file = @$('.row').data('persisted-file')
+
+  render: ->
+    # alert 'hello world'
+
+  begin_change_file: ->
+    console.log 'begin_change_file'
+
+    @$file.click()
+
+  begin_choose_file: ->
+    console.log 'begin_choose_file'
+
+    @$file.click()
+
+  change_file: (event) ->
+    console.log 'end_change_file'
+
+    text = if event.target.files then event.target.files[0].name else 'New file'
+    @$new_file.html(text)
+
+    # show new file, hide the current one ✓
+    @showEl(@$new_file) && @hideEl(@$current_file) && @hideEl(@$no_file)
+
+    # only show the cancel button ✓
+    @hideEl(@$change_btn) && @hideEl(@$delete_btn) && @hideEl(@$choose_btn) && @showEl(@$cancel_btn)
+
+  cancel_new_file: (event) ->
+    console.log 'cancel_new_file'
+
+    # hide the new file
+    @hideEl(@$new_file)
+
+    # reset the file input ✓
+    @$file.wrap('<form>').closest('form').get(0).reset()
+    @$file.unwrap()
+
+    $(@el).removeClass('mark-as-removed')
+
+    # no more mark file as deleted
+    @$remove_file.val('0')
+
+    # hide the cancel button
+    @hideEl(@$cancel_btn)
+
+    if @persisted_file
+      # show the current file ✓
+      @showEl(@$current_file)
+
+      # display the change + delete buttons ✓
+      @showEl(@$change_btn) && @showEl(@$delete_btn)
+    else
+      # show no_file
+      @showEl(@$no_file)
+
+      # display the choose button
+      @showEl(@$choose_btn)
+
+  mark_file_as_deleted: (event) ->
+    console.log 'mark_file_as_deleted'
+
+    # TODO:
+    # set true (or 1) as value for the remove_<method> hidden field
+    @$remove_file.val('1')
+
+    # add the "mark-as-removed" class to the el
+    $(@el).addClass('mark-as-removed')
+
+    # hide the change / delete buttons, show the cancel button
+    @hideEl(@$change_btn) && @hideEl(@$delete_btn) && @showEl(@$cancel_btn)
+
+  showEl: (el) -> el.removeClass('hide')
+  hideEl: (el) -> el.addClass('hide')
+
+    # TODO CHANGE FILE
+    # 1. hide current filename ✓
+    # 2. display the new name ✓
+    # 3. hide the change button ✓
+    # 4. hide the trash button ✓
+    # 5. display the cancel button ✓
+
+
+
+  # events:
+  #   'click a.change': 'toggle_change'
+  #   'click a.delete': 'toggle_delete'
+
+  # template: ->
+  #   prefix = if @options.namespace? then "#{@options.namespace}_" else ''
+  #   ich["#{prefix}#{@options.name}_file_input"]
+
+  # render: ->
+  #   url   = @model.get("#{@options.name}_url") || ''
+  #   data  =
+  #     filename: url.split('/').pop()
+  #     url:      url
+
+  #   $(@el).html(@template()(data))
+
+  #   # only in HTML 5
+  #   @$('input[type=file]').bind 'change', (event) =>
+  #     input = $(event.target)[0]
+
+  #     if input.files?
+  #       name  = $(input).prop('name')
+  #       hash  = {}
+  #       hash[name.replace("#{@model.paramRoot}[", '').replace(/]$/, '')] = input.files[0]
+  #       @model.set(hash)
+
+  #   return @
+
+  # refresh: ->
+  #   @$('input[type=file]').unbind 'change'
+  #   @states = { 'change': false, 'delete': false }
+  #   @render()
+
+  # reset: ->
+  #   @model.set_attribute @options.name, null
+  #   @model.set_attribute "#{@options.name}_url", null
+  #   @refresh()
+
+  # toggle_change: (event) ->
+  #   @_toggle event, 'change',
+  #     on_change: =>
+  #       @$('a:first').hide() & @$('input[type=file]').show() & @$('a.delete').hide()
+  #     on_cancel: =>
+  #       @$('a:first').show() & @$('input[type=file]').hide() & @$('a.delete').show()
+
+  # toggle_delete: (event) ->
+  #   @_toggle event, 'delete',
+  #     on_change: =>
+  #       @$('a:first').addClass('deleted') & @$('a.change').hide()
+  #       @$('input[type=hidden].remove-flag').val('1')
+  #       @model.set_attribute("remove_#{@options.name}", true)
+  #     on_cancel: =>
+  #       @$('a:first').removeClass('deleted') & @$('a.change').show()
+  #       @$('input[type=hidden].remove-flag').val('0')
+  #       @model.set_attribute("remove_#{@options.name}", false)
+
+  # _toggle: (event, state, options) ->
+  #   event.stopPropagation() & event.preventDefault()
+
+  #   button  = $(event.target)
+  #   label   = button.data('alt-label')
+
+  #   unless @states[state]
+  #     options.on_change()
+  #   else
+  #     options.on_cancel()
+
+  #   button.data('alt-label', button.html())
+
+  #   button.html(label)
+
+  #   @states[state] = !@states[state]
+
+  # remove: ->
+  #   @$('input[type=file]').unbind 'change'
+  #   super


paymenthistory: fix payment history list

--- client/home/lib/paymenthistory/components/invoiceslist/view.coffee
+++ client/home/lib/paymenthistory/components/invoiceslist/view.coffee
@@ -6,11 +6,11 @@

   numberOfSections: -> 1

-  numberOfRowsInSection: -> @props.invoices?.size * 3
+  numberOfRowsInSection: -> @props.invoices?.size

   renderSectionHeaderAtIndex: -> null

-  renderRowAtIndex: (sectionIndex, rowIndex) -> <SingleInvoice invoice={@props.invoices.get 0} />
+  renderRowAtIndex: (sectionIndex, rowIndex) -> <SingleInvoice invoice={@props.invoices.get rowIndex} />

   renderEmptySectionAtIndex: ->
No invoices found


fixed typo (originial => original), only test for existence of originalEvent once

--- coffee/chosen.jquery.coffee
+++ coffee/chosen.jquery.coffee
@@ -135,7 +135,7 @@
     this.results_reset(evt) if evt.target.nodeName is "ABBR" and not @is_disabled

   search_results_mousewheel: (evt) ->
-    delta = -evt.originalEvent?.wheelDelta or evt.originialEvent?.detail
+    delta = -evt.originalEvent.wheelDelta or evt.originalEvent.detail if evt.originalEvent
     if delta?
       evt.preventDefault()
       delta = delta * 40 if evt.type is 'DOMMouseScroll'


Wrap the gmaps callback in a deferred object incase the load is invoked more than once in rapid succession

--- components/geo/index.coffee
+++ components/geo/index.coffee
@@ -7,10 +7,12 @@
   loadGoogleMaps: (cb) ->
     return cb() if @googleMapsLoaded

+    @googleMapsLoading = (dfd = $.Deferred()).promise()
+
     window.googleMapsCallback = =>
+      dfd.resolve()
       @googleMapsLoaded = true
-      cb()
-      window.googleMapsCallback = undefined
+      @googleMapsLoading.then cb

     $.getScript @googleMapsAPI + '&callback=googleMapsCallback'


Handle inappropriate input

Handle inappropriate input

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/joegoldbeck/how-much-beer.git/'


test (Session) current user id should be accessible

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/AppGyver/supersonic.git/'


Added test case for "delay" function

Added test case for "delay" function

error: pathspec 'test/t1-delay.coffee' did not match any file(s) known to git

--- test/t1-delay.coffee
+++ test/t1-delay.coffee
@@ -0,0 +1,21 @@
+
+{ expect, assert } = require('chai')
+
+baselib = require './../index.coffee'
+
+{ delay } = baselib
+
+describe 'delay', ->
+
+  it 'Existence', ->
+
+    expect(baselib).to.have.property('delay')
+    .which.is.a('function')
+
+  it 'General Use Case', (done)->
+
+    timeStamp = (new Date).getTime()
+    delay 300, ->
+      now = (new Date).getTime()
+      expect(now - timeStamp).to.be.closeTo 300, 10
+      done()


Horizontally center background images.

Horizontally center background images.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Snitzle/hummingbird.git/'


Solve touchDevise. [#31]

Solve touchDevise. [#31]

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/rockandror/startup-suspender-rails4.git/'


Fix navbar Initilatisation Games with Phaser

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/GregDesplaces/classe-1914.git/'


new array functions

new array functions

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Christianjuth/Extension-Framework.git/'


fix putting focus on popup causing the popup to close under certain circumstances

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/artsyca/emberui.git/'


restore users's focus back to where it was when popup closes


added preliminary fs.watch stuff

added preliminary fs.watch stuff

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/genericdave/noprob.git/'


Rewrite fixtures

Rewrite fixtures

error: pathspec 'server/fixtures/Page.coffee' did not match any file(s) known to git

--- server/fixtures/Page.coffee
+++ server/fixtures/Page.coffee
@@ -0,0 +1,3 @@
+Fixtures.push Pages,
+  Index:
+    url: "/"


removed options

removed options

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ellisio/jquery.phone.git/'


a number of tests of the csv module

a number of tests of the csv module

error: pathspec 'dkobo/koboform/static/js/xlform/spec/spec_csv.coffee' did not match any file(s) known to git

--- dkobo/koboform/static/js/xlform/spec/spec_csv.coffee
+++ dkobo/koboform/static/js/xlform/spec/spec_csv.coffee
@@ -0,0 +1,223 @@
+describe "individual methods", ->
+  ###
+  tests individual methods including:
+  csv.to(String|Object|Objects)
+  csv.sheeted.to(String|Objects)
+  ###
+  it "doesnt cast strings to integers", ->
+    newCsv = """
+    col1,col2
+    row1,234e567
+    """
+    csvObj = csv(newCsv)
+    window.csvObj = csvObj
+    expect(csvObj.toObjects()[0].col2).not.toBe(Infinity)
+    expect(csvObj.toObjects()[0].col2).toBe("234e567")
+
+  it "works with sheeted csvs", ->
+    sheeted = csv.sheeted.toObjects(examples.sheetedCsv)
+    expect(sheetName  for own sheetName of sheeted).toEqual ['survey', 'choices', 'settings']
+
+describe "test which require csv.settings.parseFloat to be true", ->
+  ###
+  csv(...) and csv.sheeted(...) create js objects which can be converted
+  or modified.
+  ###
+  beforeEach ->
+    @csv_settings_parseFloat = csv.settings.parseFloat
+    csv.settings.parseFloat = true
+  afterEach ->
+    csv.settings.parseFloat = @csv_settings_parseFloat
+
+describe "Csv and SheetedCsv creators", ->
+  ###
+  csv(...) and csv.sheeted(...) create js objects which can be converted
+  or modified.
+  ###
+  beforeEach ->
+    @r = csv(examples.sparceCsv)
+
+  it "collects accurate column and row details from string", ->
+    cols = @r.columns
+    rowArr = @r.rowArray
+    expect(cols).toEqual ["a", "b", "c", "d"]
+    expect(rowArr.length).toBe 4
+
+  it "can add a row", ->
+    @r.addRow a: 1, b: 2, c: 3, d: 4
+    expect(@r.rowArray.length).toEqual 5
+
+  it "can add a row with a new column", ->
+    @r.addRow a: 1, b: 2, c: 3, d: 4, e: 5
+    expect(@r.columns).toEqual ["a", "b", "c", "d", "e"]
+    expect(@r.rowArray.length).toEqual 5
+
+  it "can go fowards and backwards", ->
+    checkEquality = (c1, c2)->
+      expect(c1.columns.length).toBe(c2.columns.length)
+      expect(c1.rows.length).toBe(c2.rows.length)
+      c1j = JSON.stringify c1.rowArray
+      c2j = JSON.stringify c2.rowArray
+      expect(c1j).toEqual(c2j)
+
+    checkEquality @r, csv(@r)
+    checkEquality @r, csv(@r.toString())
+    checkEquality @r, csv(@r.toObjects())
+
+  it "does sheeted csvs right", ->
+    d1 = csv.sheeted(examples.sheetedDifferent1)
+    d2 = csv.sheeted(examples.sheetedDifferent2)
+    reee = """
+    "survey",,
+    ,"label","type"
+    ,"Name:","text"
+    ,"Favorite color","select_one colors"
+    ,"Favorite type of food","select_one foods"
+    "choices",,
+    ,"list","label"
+    ,"colors","Black"
+    ,"colors","White"
+    ,"foods","Italian food"
+    ,"foods","Mexican food"
+    ,"foods","Chinese food"
+    "settings",,
+    ,"id","value"
+    ,"setting1","TRUE"
+    """
+    expect(reee).toEqual(d1.toString())
+    expect(reee).toEqual(d2.toString())
+
+describe "Creating xlsform", ->
+  it "works", ->
+    sheeted = csv.sheeted()
+    survey = csv()
+    survey.addRow label: "Your name", type: "string", hint: "type your name"
+    survey.addRow label: "Favorite color", type: "select_one colors"
+
+    expect(survey.toString()).toEqual """
+      "label","type","hint"
+      "Your name","string","type your name"
+      "Favorite color","select_one colors",
+    """
+
+    choices = csv()
+    for color in "Red Yellow Pink Green Orange Purple Blue".split " "
+      choices.addRow "list name": "colors", name: color.toLowerCase(), label: color
+
+    sheeted.sheet "survey", survey
+    sheeted.sheet "choices", choices
+
+    expect(sheeted.toString()).toEqual """
+      "survey",,,
+      ,"label","type","hint"
+      ,"Your name","string","type your name"
+      ,"Favorite color","select_one colors",
+      "choices",,,
+      ,"list name","name","label"
+      ,"colors","red","Red"
+      ,"colors","yellow","Yellow"
+      ,"colors","pink","Pink"
+      ,"colors","green","Green"
+      ,"colors","orange","Orange"
+      ,"colors","purple","Purple"
+      ,"colors","blue","Blue"
+    """
+
+describe "test escaped characters", ->
+  beforeEach ->
+    @sheet = csv()
+
+  it "normal doc works", ->
+    @sheet.addRow(name: "Aardvark", title: "Doctor")
+    expect(@sheet.toString()).toEqual """
+    "name","title"
+    "Aardvark","Doctor"
+    """
+  it "has escaped characters export correctly", ->
+    slash_text = "Has a back slash \\ here"
+    @sheet.addRow(name: slash_text, title: "Doctor")
+    expect(csv(@sheet.toString()).toObjects()[0].name).toEqual slash_text
+
+
+  it "has quotes exported correctly", ->
+    slash_text = 'This string has a quote " character'
+    @sheet.addRow(name: slash_text, title: "Doctor")
+    expect(csv(@sheet.toString()).toObjects()[0].name).toEqual slash_text
+
+@examples = {}
+
+examples.sequential = """
+  a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1,aa1
+  a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,aa2
+  a3,b3,c3,d3,e3,f3,g3,h3,i3,j3,k3,l3,m3,n3,o3,p3,q3,r3,s3,t3,u3,v3,w3,x3,y3,z3,aa3
+  a4,b4,c4,d4,e4,f4,g4,h4,i4,j4,k4,l4,m4,n4,o4,p4,q4,r4,s4,t4,u4,v4,w4,x4,y4,z4,aa4
+  a5,b5,c5,d5,e5,f5,g5,h5,i5,j5,k5,l5,m5,n5,o5,p5,q5,r5,s5,t5,u5,v5,w5,x5,y5,z5,aa5
+  a6,b6,c6,d6,e6,f6,g6,h6,i6,j6,k6,l6,m6,n6,o6,p6,q6,r6,s6,t6,u6,v6,w6,x6,y6,z6,aa6
+  a7,b7,c7,d7,e7,f7,g7,h7,i7,j7,k7,l7,m7,n7,o7,p7,q7,r7,s7,t7,u7,v7,w7,x7,y7,z7,aa7
+  a8,b8,c8,d8,e8,f8,g8,h8,i8,j8,k8,l8,m8,n8,o8,p8,q8,r8,s8,t8,u8,v8,w8,x8,y8,z8,aa8
+  a9,b9,c9,d9,e9,f9,g9,h9,i9,j9,k9,l9,m9,n9,o9,p9,q9,r9,s9,t9,u9,v9,w9,x9,y9,z9,aa9
+  a10,b10,c10,d10,e10,f10,g10,h10,i10,j10,k10,l10,m10,n10,o10,p10,q10,r10,s10,t10,u10,v10,w10,x10,y10,z10,aa10
+  a11,b11,c11,d11,e11,f11,g11,h11,i11,j11,k11,l11,m11,n11,o11,p11,q11,r11,s11,t11,u11,v11,w11,x11,y11,z11,aa11
+"""
+
+examples.sparceCsv = """
+  a,b,c,d
+  1,,,
+  1,2,,
+  3,4,5,
+  5,,,33
+"""
+
+examples.sheetedCsv = """
+  survey
+  ,label,type
+  ,Name:,text
+  ,"Favorite color","select_one colors"
+  choices,,
+  ,list,label
+  ,colors,Black
+  ,colors,White
+  settings,col1,col2
+  ,setting1,true
+  ,setting2,false
+"""
+
+examples.sheetedDifferent1 = """
+  survey,label,type
+  choices,list,label
+  ,,
+  ,,
+  survey,Name:,text
+  ,,
+  survey,"Favorite color","select_one colors"
+  choices,colors,Black
+  ,colors,White
+  ,,
+  ,,
+  survey,"Favorite type of food","select_one foods"
+  choices,foods,"Italian food"
+  ,foods,"Mexican food"
+  ,foods,"Chinese food"
+  ,,
+  ,,
+  settings,,
+  ,id,value
+  ,setting1,TRUE
+"""
+
+examples.sheetedDifferent2 = """
+  survey,label,type
+  ,Name:,text
+  ,"Favorite color","select_one colors"
+  ,"Favorite type of food","select_one foods"
+  choices,,
+  ,list,label
+  ,colors,Black
+  ,colors,White
+  ,foods,"Italian food"
+  ,foods,"Mexican food"
+  ,foods,"Chinese food"
+  settings,,
+  ,id,value
+  ,setting1,TRUE
+"""


expire

expire

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/stevelacy/claru.git/'


Log client errors

Log client errors

--- client/app/initialize.coffee
+++ client/app/initialize.coffee
@@ -78,10 +78,6 @@
                 console.log "Spinner class not available."
                 null

-        setTimeout ->
-            console.log titi
-        , 5000
-
     catch e
         console.error e, e?.stack
         exception = e.toString()


fixed error when rooms are unsubscribed

fixed error when rooms are unsubscribed

--- client/views/app/room.coffee
+++ client/views/app/room.coffee
@@ -186,7 +186,7 @@
 		users = []
 		onlineUsers = RoomManager.onlineUsers.get()

-		for username in room.usernames
+		for username in room?.usernames or []
 			if onlineUsers[username]?
 				users.push
 					username: username


Forgot a file...

Forgot a file...

error: pathspec 'app/assets/javascripts/backbone/views/tracks/tracks.js.coffee' did not match any file(s) known to git

--- app/assets/javascripts/backbone/views/tracks/tracks.js.coffee
+++ app/assets/javascripts/backbone/views/tracks/tracks.js.coffee
@@ -0,0 +1,22 @@
+Molamp.Views.Tracks ||= {}
+
+class Molamp.Views.Tracks.TracksView extends Backbone.View
+  el: '#top-tracks table tbody'
+
+  initialize: ->
+    @.model.bind 'add', @.addOne, @
+
+  addOne: (track) =>
+    view = new Molamp.Views.Tracks.TrackView model: track
+
+    $(@.el).append view.render().$el
+
+  addAll: ->
+    $(@.el).html ''
+
+    @.model.each @.addOne
+
+  render: ->
+    @.addAll()
+
+    @


Added angularytics config to javascripts/helpers

error: pathspec 'app/assets/javascripts/sprangular/helpers/angularytics.coffee' did not match any file(s) known to git

--- app/assets/javascripts/sprangular/helpers/angularytics.coffee
+++ app/assets/javascripts/sprangular/helpers/angularytics.coffee
@@ -0,0 +1,6 @@
+Sprangular
+  .config (AngularyticsProvider) ->
+    AngularyticsProvider.setEventHandlers(['Console', 'GoogleUniversal'])
+
+  .run (Angularytics) ->
+    Angularytics.init()


Just send the properties to the db

Just send the properties to the db

--- lib/db.coffee
+++ lib/db.coffee
@@ -52,31 +52,32 @@
         callback(found)

   ## CREATE
-  add: (project, callback) ->
+  add: (props, callback) ->
     projects = CSON.readFileSync(@file()) || {}
-    id = project.title.replace(/\s+/g, '').toLowerCase()
+    id = props.title.replace(/\s+/g, '').toLowerCase()

-    projects[id] = project
-    successMessage = "#{project.title} has been added"
-    errorMessage = "#{project.title} could not be saved"
+    projects[id] = props
+    successMessage = "#{project.props.title} has been added"
+    errorMessage = "#{project.props.title} could not be saved"

     CSON.writeFile @file(), projects, (err) ->
       unless err
         atom.notifications?.addSuccess successMessage
-        project._id = id
-        callback(project)
+        props._id = id
+        callback(props)
       else
         atom.notifications?.addError errorMessage

   ## UPDATE
-  update: (project, callback) ->
-    return false if not project._id
+  update: (props, callback) ->
+    return false if not props._id

     CSON.readFile @file(), (error, results) =>
       unless error
-        for key, value in results
-          if key is project._id
-            results[key] = project
+        for key, value of results
+          if key is props._id
+            delete(props._id)
+            results[key] = props

       CSON.writeFile @file(), results, (err)  ->
         if err


logging stats

logging stats

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/AppCivico/votolegal-www.git/'