test for channel creation

test for channel creation

error: pathspec 'test/testChannels.spec.coffee' did not match any file(s) known to git

--- test/testChannels.spec.coffee
+++ test/testChannels.spec.coffee
@@ -0,0 +1,97 @@
+coux = require('coux').coux
+userChannelControl = require '../lib/userChannelControl'
+docstate = require('docstate')
+
+testAppConfig =
+  "host" : "http://localhost:5984"
+  "control-db" : "test-control",
+  channelTemplate : "test-template"
+testDb = [testAppConfig.host,  testAppConfig["control-db"]].join '/'
+testTemplate = [testAppConfig.host,  testAppConfig["channelTemplate"]].join '/'
+
+
+bindControlDb = () ->
+  control = docstate.control()
+  userChannelControl.bind(control, testAppConfig, testAppConfig["control-db"])
+  control.start()
+  coux.subscribeDb(testDb,(change) ->
+    control.handle(change.doc))
+
+
+waitForDoc = (db, id, seq, cb) ->
+  couxOpts =
+    url : db+"/_changes?filter=_doc_ids&since="+seq+"&include_docs=true&feed=longpoll"
+    agent : false
+  coux.post couxOpts, {"doc_ids": [ id]}, (err, resp) ->
+    # console.log err, resp
+    cb(err, resp.results[0].doc)
+
+
+createTemplate = (cb) ->
+  coux.del testTemplate, ->
+    coux.put testTemplate, ->
+      coux.put [testTemplate, 'test-doc'], foobar : "ok", ->
+        cb()
+
+createDatabase = (cb) ->
+  coux.del testDb, ->
+    coux.put testDb, ->
+      cb()
+
+describe 'userChannelControl', ->
+  changesPromise = false
+  it 'with a control database', ->
+    createDatabase ->
+      coux testDb, (err, info) ->
+        expect(info.db_name).toEqual "test-control"
+        changesPromise = bindControlDb(true)
+        asyncSpecDone()
+    asyncSpecWait()
+
+  it 'with a channel template', ->
+    createTemplate ->
+      coux [testTemplate, 'test-doc'], (err, doc) ->
+        expect(doc.foobar).toEqual "ok"
+        asyncSpecDone()
+    asyncSpecWait()
+
+  describe "creating a channel", ->
+    chId = false
+    cloudDb = false
+    newChannelDoc =
+      type : "channel"
+      state : "new"
+
+    it "with a new channel document", ->
+      coux.post testDb, newChannelDoc, (err, ok) ->
+        chId = ok.id
+        expect(ok.id).not.toBeNull()
+        asyncSpecDone()
+      asyncSpecWait()
+
+    it 'should update the document', ->
+      waitForDoc testDb, chId, 1, (err, doc) ->
+        expect(doc.state).toEqual "ready"
+        cloudDb = doc.cloud_database
+        asyncSpecDone()
+      asyncSpecWait()
+
+    it 'should set up a cloud database', ->
+      coux [testAppConfig.host, cloudDb], (err, info) ->
+        expect(info.db_name).toEqual cloudDb
+        changesPromise.stop()
+        asyncSpecDone()
+      asyncSpecWait()
+
+    it 'should install the channel template', ->
+      coux [testAppConfig.host, cloudDb, 'test-doc'], (err, doc) ->
+        expect(doc.foobar).toEqual "ok"
+        asyncSpecDone()
+      asyncSpecWait()
+
+    it 'should add the user to the security object members list', ->
+      coux [testAppConfig.host, cloudDb, '_security'], (err, doc) ->
+        expect(doc.members).toBeDefined()
+        # expect(doc.members.names[0]).toEqual "our user name"
+        asyncSpecDone()
+      asyncSpecWait()


'allow reacting' should be a toggle option (#6522)

--- packages/rocketchat-channel-settings/client/views/channelSettings.coffee
+++ packages/rocketchat-channel-settings/client/views/channelSettings.coffee
@@ -232,6 +232,7 @@
 		reactWhenReadOnly:
 			type: 'boolean'
 			label: 'React_when_read_only'
+			isToggle: true
 			processing: new ReactiveVar(false)
 			canView: (room) => room.t isnt 'd' and room.ro
 			canEdit: (room) => RocketChat.authz.hasAllPermission('set-react-when-readonly', room._id)


Remove uncessary log

Remove uncessary log

--- packages/rocketchat-channel-settings/client/views/channelSettings.coffee
+++ packages/rocketchat-channel-settings/client/views/channelSettings.coffee
@@ -145,7 +145,6 @@
 			canView: (room) => room.t in ['c', 'p']
 			canEdit: (room) => RocketChat.authz.hasAllPermission('edit-room', room._id)
 			save: (value, room) ->
-				console.log value
 				if value not in ['c', 'p']
 					return toastr.error t('error-invalid-room-type', value)


pass supersonic.data.model smoke test by adding steroids data headers to whitelist

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/'


add slugifier as helper

add slugifier as helper

error: pathspec 'lib/slug.coffee' did not match any file(s) known to git


Disable a flaky ORA Javascript test.

Disable a flaky ORA Javascript test.

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/bmedx/modulestore.git/'


Add in next_problem jasmine tests

Add in next_problem jasmine tests


Remove sync() method and improve some docs.

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/RobotSnacks/stout-orm.git/'


edit snippets

edit snippets

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/AlexKVal/dotfiles.git/'


JWorkspace::createDefault: use nickname of owner

--- workers/social/lib/social/models/workspace.coffee
+++ workers/social/lib/social/models/workspace.coffee
@@ -194,6 +194,8 @@

           return callback err  if err

+          {nickname}     = account.profile
+
           data           =
             name         : 'My Workspace'
             isDefault    : yes


Sortable will now not allow you to drag an li onto another li which is not draggable. This allows you to make items in the list which maintain their position.

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/lonelyplanet/rizzo.git/'


Remove hover swap

Remove hover swap

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/human-nyc/spree_obesityandspeed.git/'


Flattened the queries the NewAchievementModal creates.

--- app/views/editor/level/modals/NewAchievementModal.coffee
+++ app/views/editor/level/modals/NewAchievementModal.coffee
@@ -28,22 +28,13 @@
   createQuery: ->
     checked = @$el.find('[name=queryOptions]:checked')
     checkedValues = ($(check).val() for check in checked)
-    subQueries = []
+    query = {}
     for id in checkedValues
       switch id
         when 'misc-level-completion'
-          subQueries.push state: complete: true
-        else # It's a goal
-          q = state: goalStates: {}
-          q.state.goalStates[id] = {}
-          q.state.goalStates[id].status = 'success'
-          subQueries.push q
-    unless subQueries.length
-      query = {}
-    else if subQueries.length is 1
-      query = subQueries[0]
-    else
-      query = $or: subQueries
+          query['state.complete'] = true
+        else
+          query["state.goalStates.#{id}.status"] = 'success'
     query['level.original'] = @level.get 'original'
     query


Fixed bugs in add camera widget.

Fixed bugs in add camera widget.

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/evercam/evercam-dashboard.git/'


client/app: remove unused modules from /navigation

Signed-off-by: Umut Sirin <4055abbc0e40a1254e715b952ccd414607e0b365@gmail.com>

--- client/app/lib/navigation/navigationmachineitem.coffee
+++ client/app/lib/navigation/navigationmachineitem.coffee
@@ -1,324 +0,0 @@
-kd                           = require 'kd'
-htmlencode                   = require 'htmlencode'
-
-JView                        = require 'app/jview'
-KDCustomHTMLView             = kd.CustomHTMLView
-KDProgressBarView            = kd.ProgressBarView
-
-Machine                      = require 'app/providers/machine'
-groupifyLink                 = require 'app/util/groupifyLink'
-isMachineSettingsIconEnabled = require 'app/util/isMachineSettingsIconEnabled'
-userEnvironmentDataProvider  = require 'app/userenvironmentdataprovider'
-
-SidebarMachineSharePopup     = require 'app/activity/sidebar/sidebarmachinesharepopup'
-SidebarMachineConnectedPopup = require 'app/activity/sidebar/sidebarmachineconnectedpopup'
-
-
-module.exports = class NavigationMachineItem extends JView
-
-  { Running, Stopped } = Machine.State
-
-  stateClasses  = 'reconnecting '
-  stateClasses += "#{state.toLowerCase()} " for state in Object.keys Machine.State
-
-
-  constructor: (options = {}, data) ->
-
-    { machine, workspaces } = data
-
-    @alias           = machine.slug or machine.label
-    machineOwner     = machine.getOwner()
-    reassigned       = machine.jMachine.meta?.oldOwner?
-    oldOwner         = machine.jMachine.meta?.oldOwner ? machineOwner
-    isMyMachine      = machine.isMine()
-    machineRoutes    =
-      own            : "/IDE/#{@alias}"
-      collaboration  : "/IDE/#{@getChannelId data}"
-      permanentShare : "/IDE/#{machine.uid}"
-      reassigned     : "/IDE/#{machine.uid}"
-
-    machineType = 'own'
-
-    if reassigned
-      machineType = 'reassigned'
-    else if not isMyMachine
-      machineType = if machine.isPermanent() then 'permanentShare' else 'collaboration'
-
-    @machineRoute = groupifyLink machineRoutes[machineType]
-
-    options.tagName    = 'a'
-    options.cssClass   = "vm #{machine.status.state.toLowerCase()} #{machine.provider}"
-    options.attributes =
-      href             : '#'
-      title            : "Open IDE for #{@alias}"
-
-    unless isMyMachine
-      options.attributes.title += " (shared by @#{htmlencode.htmlDecode machineOwner})"
-
-    super options, data
-
-    { computeController } = kd.singletons
-
-    { @machine } = @getData()
-    labelPartial = machine.label or @alias
-
-    if not isMyMachine or reassigned
-      labelPartial = """
-        #{labelPartial}
-        <cite class='shared-by'>
-          (@#{htmlencode.htmlDecode oldOwner})
-        </cite>
-      """
-
-    @label     = new KDCustomHTMLView
-      partial  : labelPartial
-
-    @progress  = new KDProgressBarView
-      cssClass : 'hidden'
-
-    @createSettingsIcon()
-
-    computeController
-      .on "reconnecting-#{@machine.uid}", =>
-        @setState 'reconnecting'
-
-      .on "public-#{@machine._id}", (event) =>
-        @handleMachineEvent event
-
-    computeController.ready =>
-
-      if stack = computeController.findStackFromMachineId @machine._id
-        computeController.on "public-#{stack._id}", (event) =>
-          @handleMachineEvent event
-
-    if not @machine.isMine() and not @machine.isApproved()
-      @showSharePopup()
-
-    @subscribeMachineShareEvent()
-
-
-  createSettingsIcon: ->
-
-    isMine     = @machine.isMine()
-    isApproved = @machine.isApproved()
-    cssClass   = if (isMine or isApproved) and @settingsEnabled() then '' else 'hidden'
-
-    @settingsIcon = new KDCustomHTMLView
-      tagName     : 'span'
-      cssClass    : "settings-icon #{cssClass}"
-      click       : (e) =>
-        kd.utils.stopDOMEvent e
-
-        return  unless @settingsEnabled()
-
-        if @machine.isMine() then @handleMachineSettingsClick()
-        else if @machine.isApproved() then @showSharePopup()
-
-
-  moveSettingsIconLeft : ->
-
-    @settingsIcon.setClass 'move-left'
-
-
-  resetSettingsIconPosition : ->
-
-    @settingsIcon.unsetClass 'move-left'
-
-
-  settingsEnabled: -> isMachineSettingsIconEnabled @machine
-
-
-  handleMachineSettingsClick: ->
-
-    return  if not @settingsEnabled()
-
-    kd.singletons.router.handleRoute "/Machines/#{@machine.uid}"
-
-
-  getPopupPosition: (extraTop = 0) ->
-
-    bounds   = @getBounds()
-    position =
-      top    : Math.max(bounds.y - 38, 0) + extraTop
-      left   : bounds.x + bounds.w + 16
-
-    return position
-
-
-  handleMachineEvent: (event) ->
-
-    { percentage, status } = event
-
-    # switch status
-    #   when Machine.State.Terminated then @destroy()
-    #  else @setState status
-
-    @setState status
-
-    if percentage?
-      @updateProgressBar percentage
-
-
-  setState: (state) ->
-
-    return  unless state
-
-    @unsetClass stateClasses
-    @setClass state.toLowerCase()
-
-
-  updateProgressBar: (percentage) ->
-
-    return @progress.hide()  unless percentage
-
-    @progress.show()
-    @progress.updateBar percentage
-
-    if percentage is 100
-      kd.utils.wait 1000, @progress.bound 'hide'
-
-
-  # passing data is required because this method is called before super call.
-  getChannelId: (data) ->
-
-    return data.workspaces.first?.channelId
-
-
-  popups = {}
-
-  ###
-
-  This function determines what sort of machine share popup should be
-  displayed based on given options and registered invitations in
-  `MachineShareManager`.
-
-  If an invitation found for machine given to `NavigationMachineItem`
-  instance then share popup is displayed in invitation type for the
-  shared workspace attached in invitation object.
-
-  Default behavior of `SidebarMachineSharePopup` instance satisfies
-  `shared machine` invitations.
-
-  If an invitation is not found then state of invitations deduced by
-  checking related properties.
-
-  If user is a permanent user then approve state of `JMachine`
-  determines type of share popup.
-
-  If user is not a permanent user then share popup type is set to
-  `collaboration`.  If a workspace identifier is given in options then
-  associated `JWorkspace` is found.  Channel identifier is set from
-  matching workspace object.
-
-  Collaboration invitation is displayed if user is not a participant
-  of associated channel.
-
-  ###
-  showSharePopup: (options = {}) ->
-
-    { machineShareManager } = kd.singletons
-
-    show = (options) =>
-      kd.utils.wait 733, =>
-        options.position = @getPopupPosition 20
-        popup = popups[@machine.uid]
-        kd.utils.defer -> popup?.destroy()
-        popups[@machine.uid] = new SidebarMachineSharePopup options, @machine
-        machineShareManager.registerChannelEvent options.channelId
-
-
-    if invitation = machineShareManager.get @machine.uid
-      { type } = invitation
-
-      options.type = type
-
-      switch type
-        when 'collaboration'
-          options.isApproved = no
-
-          return userEnvironmentDataProvider.fetchMachineByUId @machine.uid, (machine, workspaces) ->
-            for workspace in workspaces when workspace.getId() is invitation.workspaceId
-              break
-
-            options.channelId = workspace.channelId
-            show options
-
-      return show options
-
-    else if @machine.isPermanent()
-      options.type = 'shared machine'
-      options.isApproved = @machine.isApproved()
-      show options
-
-    else if not @machine.isPermanent()
-      options.type = 'collaboration'
-
-      return userEnvironmentDataProvider.fetchMachineByUId @machine.uid, (machine, workspaces) ->
-        for workspace in workspaces
-          if options.workspaceId and workspace.getId() isnt options.workspaceId
-            continue
-          else if not options.workspaceId and not workspace.channelId
-            continue
-
-          { channelId } = workspace
-          break
-
-        return  unless options.channelId = channelId
-
-        kd.singletons.socialapi.channel.byId { id: channelId }, (err, channel) ->
-
-          return console.error err  if err
-          options.isApproved = channel.isParticipant
-
-          show options
-
-
-  showMachineConnectedPopup: (params) ->
-
-    slug = "#{@machine.uid}ConnectedPopup"
-
-    options    =
-      position : @getPopupPosition 13
-      provider : params.providerName
-
-    popup = popups[slug]
-    kd.utils.defer -> popup?.destroy()
-
-    popups[slug] = new SidebarMachineConnectedPopup options, @machine
-
-
-  subscribeMachineShareEvent: ->
-
-    { machineShareManager } = kd.singletons
-    machineShareManager.subscribe @machine.uid, @bound 'showSharePopup'
-
-    @once 'KDObjectWillBeDestroyed', =>
-      machineShareManager.unsubscribe @machine.uid, @bound 'showSharePopup'
-
-
-  click: (e) ->
-
-    m = @machine
-
-    if not m.isMine() and not m.isApproved()
-      kd.utils.stopDOMEvent e
-      @showSharePopup()
-
-    super
-
-
-  destroy: ->
-
-    popup.destroy()  for __, popup of popups
-
-    super
-
-
-  pistachio: ->
-
-    return '''
-      <figure></figure>
-      {{> @label}}
-      {{> @settingsIcon}}
-      {{> @progress}}
-    '''


send the state to ES, not its comparison

--- client/Terminal/AppView.coffee
+++ client/Terminal/AppView.coffee
@@ -379,13 +379,16 @@

       unless vm
         ErrorLog.create "terminal: handlePlusClick error", {reason:"0 vms"}
+        return

       osKite =
         if KD.useNewKites
         then vmc.kites.oskite[vm.hostnameAlias]
         else vmc.kites[vm.hostnameAlias]

-      if state = osKite.recentState?.state is 'RUNNING'
+      state = osKite.recentState?.state
+
+      if state is 'RUNNING'
       then @prepareAndRunTerminal vm
       else
         ErrorLog.create "terminal: handlePlusClick error",


Execute callback in both branches

Execute callback in both branches

Adding shared tab to own dashboard failed if user had no tabs in
configuration yet because the callback was not executed in that case.
Fix this.

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/leonidas/qa-dashboard.git/'


Sliderbar Component: HandleView separated to a new file.

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/andrewjcasal/koding.git/'


activity: fix delegate event listener bindings in `ActivityActionsView` class

--- client/Social/Activity/views/activityactions.coffee
+++ client/Social/Activity/views/activityactions.coffee
@@ -53,15 +53,9 @@
       loaderOptions :
         color       : '#6B727B'

-    @attachListeners()
-
-
-  attachListeners: ->
-
-    commentList = @getDelegate()
-
-    commentList.on 'BackgroundActivityStarted',  @loader.bound 'show'
-    commentList.on 'BackgroundActivityFinished', @loader.bound 'hide'
+    options.delegate
+      .on "AsyncJobStarted",  @loader.bound "show"
+      .on "AsyncJobFinished", @loader.bound "hide"

   reply: (click) ->


add test that should fail

add test that should fail

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

--- test/test8.coffee
+++ test/test8.coffee
@@ -0,0 +1,8 @@
+# out: test8.js
+
+this <<< is no valid coffeescript
+
+module.exports =
+  a: 'a'
+  b: ->
+    abcdefg = 'abcdefg'


Add unit test for yoclient

Add unit test for yoclient

error: pathspec 'test/helpers/yoclient.coffee' did not match any file(s) known to git

--- test/helpers/yoclient.coffee
+++ test/helpers/yoclient.coffee
@@ -0,0 +1,9 @@
+chai = require 'chai'
+
+yoclient = require '../../src/helpers/yoclient'
+
+expect = chai.expect
+
+describe 'Helper: yoclient', ->
+  it 'should have methods', ->
+    expect(yoclient).to.respondTo('send')


group: update transferOwnership func signature

--- workers/social/lib/social/models/group/index.coffee
+++ workers/social/lib/social/models/group/index.coffee
@@ -200,7 +200,7 @@
           (signature Object, Function)
         ]
         transferOwnership:
-          (signature String, Function)
+          (signature Object, Function)
         destroy:
           (signature String, Function)
         addSubscription:
@@ -1471,10 +1471,13 @@
       { permission: 'grant permissions' }
       { permission: 'grant permissions', superadmin: yes }
     ]
-    success: (client, accountId, callback) ->
-      JAccount = require '../account'
+    success: (client, options, callback) ->

       { delegate } = client.connection
+      { accountId, currentPassword, slug } = options
+
+      return callback new KodingError 'User is not selected!'  unless accountId
+
       if delegate.getId().equals accountId
         return callback new KodingError 'You cannot transfer ownership to yourself, concentrate and try again!'


test for filter

test for filter

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

--- test/filter/filter.coffee
+++ test/filter/filter.coffee
@@ -0,0 +1,107 @@
+
+Test('filter-filter-0').run ($test, alight) ->
+    if not alight.filters.filter
+        return 'skip'
+    $test.start 5
+
+    scope =
+        list: [
+            { name: 'linux 1' }
+            { name: 'ubuntu 2' }
+            { name: 'red hat 4', k: 'kind' }
+            { name: 'windows 8', k: 'kind' }
+        ]
+        text: ''
+    cd = alight.ChangeDetector scope
+
+    resultList = []
+
+    cd.watch 'list | filter text "name"', (value) ->
+        resultList = value
+    ,
+        isArray: true
+
+    result = ->
+        sum = 0
+        for i in resultList
+            sum += Number i.name.match(/\d+/)
+        sum
+
+    cd.scan()
+    $test.equal result(), 15
+
+    scope.list.push
+        name: 'macos X 16'
+    scope.list.push
+        name: 'freebds 32'
+
+    cd.scan ->
+        $test.equal result(), 63
+
+        scope.text = 'u'
+        cd.scan ->
+            $test.equal result(), 3
+
+            scope.text = 's'
+            cd.scan ->
+                $test.equal result(), 8+16+32
+
+                scope.text = 'kin'
+                cd.scan ->
+                    $test.equal result(), 0
+
+                    $test.close()
+
+
+Test('filter-filter-1').run ($test, alight) ->
+    if not alight.filters.filter
+        return 'skip'
+    $test.start 5
+
+    scope =
+        list: [
+            { name: 'linux 1' }
+            { name: 'ubuntu 2' }
+            { name: 'red hat 4', k: 'kind u' }
+            { name: 'windows 8', k: 'kind' }
+        ]
+        text: ''
+    cd = alight.ChangeDetector scope
+
+    resultList = []
+
+    cd.watch 'list | filter text', (value) ->
+        resultList = value
+    ,
+        isArray: true
+
+    result = ->
+        sum = 0
+        for i in resultList
+            sum += Number i.name.match(/\d+/)
+        sum
+
+    cd.scan()
+    $test.equal result(), 15
+
+    scope.list.push
+        name: 'macos X 16'
+    scope.list.push
+        name: 'freebds 32'
+
+    cd.scan ->
+        $test.equal result(), 63
+
+        scope.text = 'u'
+        cd.scan ->
+            $test.equal result(), 7
+
+            scope.text = 's'
+            cd.scan ->
+                $test.equal result(), 8+16+32
+
+                scope.text = 'kin'
+                cd.scan ->
+                    $test.equal result(), 12
+
+                    $test.close()


coffee: initialize GitHubAccount, invoke onClickSignIn when button is clicked

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/rremizov/github-notifier.git/'


Model no longers sets role

Model no longers sets role

[#102460178]

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/netguru/people.git/'


Show only active users when filtering

Show only active users when filtering


removed duplicate method

removed duplicate method

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/bitex-la/pochette-web.git/'


feat(config-detail):reset googleId if operation changed from update to create

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/keboola/kbc-ui-wr-google-drive.git/'


Reenabling on surface mouse moved.

Reenabling on surface mouse moved.

--- app/views/editor/level/thangs/ThangsTabView.coffee
+++ app/views/editor/level/thangs/ThangsTabView.coffee
@@ -384,7 +384,7 @@
     return unless @addThangSprite
     wop = @surface.camera.screenToWorld x: e.x, y: e.y
     wop.z = 0.5
-    #@adjustThangPos @addThangSprite, @addThangSprite.thang, wop  # TODO: this and onSpriteDragged both conflictin'
+    @adjustThangPos @addThangSprite, @addThangSprite.thang, wop  # TODO: this and onSpriteDragged both conflictin'
     null

   onSurfaceMouseOver: (e) ->


Fixed error for non-course hero victory modals.

--- app/views/play/level/modal/HeroVictoryModal.coffee
+++ app/views/play/level/modal/HeroVictoryModal.coffee
@@ -68,7 +68,7 @@
   destroy: ->
     clearInterval @sequentialAnimationInterval
     @saveReview() if @$el.find('.review textarea').val()
-    @feedback.off()
+    @feedback?.off()
     super()

   onHidden: ->


Add Broker mixin to bongo client

Add Broker mixin to bongo client


Bootstrap basic tests.

Bootstrap basic tests.

error: pathspec 'spec/javascripts/application/pods_list_spec.js.coffee' did not match any file(s) known to git

--- spec/javascripts/application/pods_list_spec.js.coffee
+++ spec/javascripts/application/pods_list_spec.js.coffee
@@ -0,0 +1,13 @@
+describe 'PodsList', ->
+  it 'is empty', ->
+    subject = new PodsList(0, [], 0, 0)
+    expect(subject.totalCount).to.eql(0)
+    expect(subject.currentPods).to.eql([])
+    expect(subject.index).to.eql(0)
+    expect(subject.maxPerPage).to.eql(0)
+  it 'contains 1', ->
+    subject = new PodsList(1, [{}], 0, 0)
+    expect(subject.totalCount).to.eql(1)
+    expect(subject.currentPods).to.eql([{}])
+    expect(subject.index).to.eql(0)
+    expect(subject.maxPerPage).to.eql(0)


tableverse/shape: Add initial, very limited, Shape thingy, the first kinetic_thingy_delegate thingy.

error: pathspec 'Oghma/tableverse/shape.coffee' did not match any file(s) known to git

--- Oghma/tableverse/shape.coffee
+++ Oghma/tableverse/shape.coffee
@@ -0,0 +1,76 @@
+# Copyright 2010-2014 Christopher Alfeld
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+Oghma = @Oghma ?= {}
+Oghma.Thingy ?= {}
+
+c_layer = 'annotations'
+
+Oghma.Thingy.Tableverse.register( ( thingyverse, O ) ->
+
+  class ShapeDelegate extends Oghma.KineticThingyDelegate
+    draw: ->
+      if @thingy().gets( 'shape' ) != 'rectangle'
+        throw "Unsupported shape: #{shape}"
+
+      if ! @__k?
+        @__k = new Kinetic.Rect()
+        @group().add( @__k )
+
+      [ fill, stroke, width, height ] =
+        @thingy().geta( 'fill', 'stroke', 'width', 'height' )
+      @__k.setAttrs(
+        fill:   fill
+        stroke: stroke
+        width:  width
+        height: height
+        x:      -width / 2
+        y:      -height / 2
+      )
+
+    remove: ( thingy ) ->
+      thingyverse.dice.remove( thingy )
+      super thingy
+
+  thingyverse.shapes = new Heron.Index.MapIndex( 'owner' )
+
+  thingyverse.define(
+    'shape',
+    [
+      'owner',
+      'shape',
+      'fill', 'stroke'
+    ],
+    {
+      loc:    [ 'x', 'y', 'width', 'height' ]
+      status: [ 'locked', 'visible_to', 'zindex' ]
+    },
+    ( attrs ) ->
+      attrs.shape  ?= 'rectangle'
+      attrs.fill   ?= O.me().gets( 'primary' )
+      attrs.stroke ?= O.me().gets( 'secondary' )
+      attrs.width  ?= 20
+      attrs.height ?= 20
+
+      @after_construction( =>
+        thingyverse.shapes.add( this )
+      )
+
+      new ShapeDelegate(
+        O, this, O.layer[ c_layer ], O.zindex[ c_layer ],
+        [ 'shape', 'fill', 'stroke' ],
+        attrs
+      )
+  )
+)


focus jump to today on first due date

focus jump to today on first due date

fixes CNVS-12968

If you have multiple assignments in a syllabus that have the same
due date and you click on "Jump to Today" it focuses you on the last
item in the list. This fix makes it focus you on the first item in the
list.

--- Test Plan ---
As a user
Given I have multiple assignments that are on the same day and that day
is today
And I'm on the syllabus page
When I click on the "Jump to Today" link
Then I should be scrolled down to the assignments for that day
And I should be focused on the first assignment for that day

Change-Id: I514de278ed77567168e2b42c0cda96e673ba284e
Reviewed-on: https://gerrit.instructure.com/35994
Reviewed-by: Jeremy Stanley <b3f594e10a9edcf5413cf1190121d45078c62290@instructure.com>
QA-Review: Clare Strong <40d6bb3ed7fef516c73274131d5a837c16de74fd@instructure.com>
Tested-by: Jenkins <d95b56ce41a2e1ac4cecdd398defd7414407cc08@instructure.com>
Product-Review: Bracken Mosbacker <48b846001bca4166dc3fb7711563afc17525921e@instructure.com>

--- app/coffeescripts/behaviors/SyllabusBehaviors.coffee
+++ app/coffeescripts/behaviors/SyllabusBehaviors.coffee
@@ -119,7 +119,7 @@
       $('tr.selected').removeClass('selected')
       $row.addClass('selected')
       $('html, body').scrollTo $row
-      $row.find('a').focus()
+      $row.find('a').first().focus()

   selectDate = (date) ->
     $('.mini_month .day.selected').removeClass('selected')


Add privacy policy

Add privacy policy

--- assets/javascripts/templates/pages/about_tmpl.coffee
+++ assets/javascripts/templates/pages/about_tmpl.coffee
@@ -6,6 +6,7 @@

FAQ

Copyright

Plugins
+
Privacy Policy

@@ -72,6 +73,16 @@

Brackets extension

You can also use Fluid to turn DevDocs into a real OS X app, or Fogger on Ubuntu.
+
+
Privacy Policy

+

+
devdocs.io ("App") is operated by Thibaut Courouble ("We").
+
We do not collect personal information.
+
We use Google Analytics, Gauges and Sentry to collect anonymous traffic information and improve the app.
+
The app uses cookies to store user preferences.
+
By using the app, you signify your acceptance of this policy. If you do not agree to this policy, please do not use the app.
+
If you have any questions regarding privacy, please email thibaut@devdocs.io.
+

 """

 credits = [


Update example.coffee 変数名の修正

Update example.coffee
変数名の修正

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/askdkc/cb_slackbot.git/'


'data-localized'

'data-localized'

--- lib/main.coffee
+++ lib/main.coffee
@@ -87,12 +87,14 @@

     # Keybindings
     info = sv.querySelector('.keybinding-panel>div:nth-child(2)')
-    info.querySelector('span:nth-child(2)').textContent = "これらのキーバインドは　"
-    info.querySelector('span:nth-child(4)').textContent = "をクリック（コピー）して"
-    info.querySelector('a.link').textContent = " キーマップファイル "
-    span = document.createElement('span')
-    span.textContent = "に貼り付けると上書きできます。"
-    info.appendChild(span)
+    unless isAlreadyLocalized(info)
+      info.querySelector('span:nth-child(2)').textContent = "これらのキーバインドは　"
+      info.querySelector('span:nth-child(4)').textContent = "をクリック（コピー）して"
+      info.querySelector('a.link').textContent = " キーマップファイル "
+      span = document.createElement('span')
+      span.textContent = "に貼り付けると上書きできます。"
+      info.appendChild(span)
+      info.setAttribute('data-localized', 'true')

     # Themes panel
     info = sv.querySelector('.themes-panel>div>div:nth-child(2)')
@@ -132,6 +134,7 @@

   applySpecialHeading = (area, org, childIdx, text) ->
     sh = getTextMatchElement(area, '.section-heading', org)
+    return unless sh
     sh.childNodes[childIdx].textContent = null
     span = document.createElement('span')
     span.textContent = org
@@ -141,16 +144,28 @@
   applySectionHeadings = (area) ->
     for sh in window.JapaneseMenu.defS.Settings.sectionHeadings
       el = getTextMatchElement(area, '.section-heading', sh.label)
+      continue unless el
       applyTextWithOrg(el, sh.value)
     for sh in window.JapaneseMenu.defS.Settings.subSectionHeadings
       el = getTextMatchElement(area, '.sub-section-heading', sh.label)
+      continue unless el
       applyTextWithOrg(el, sh.value)

   getTextMatchElement = (area, query, text) ->
     elems = area.querySelectorAll(query)
+    result
     for el in elems
-      return el if el.textContent.includes(text)
-    null
+      if el.textContent.includes(text)
+        result = el
+        break
+    if isAlreadyLocalized(result)
+      return null
+    else
+      return result
+
+  isAlreadyLocalized = (elem) ->
+    localized = elem.getAttribute('data-localized') if elem
+    return localized == 'true'

   applyTextContentBySettingsId = (data) ->
     el = document.querySelector("[id='#{data.id}']")
@@ -165,5 +180,6 @@
     return if before == text
     elem.textContent = text
     elem.setAttribute('title', before)
+    elem.setAttribute('data-localized', 'true')

 module.exports = window.JapaneseMenu = new JapaneseMenu()


GitLab: Require all event handlers

GitLab: Require all event handlers


Fixes issues with dragging thangs onto the map

--- app/lib/surface/Surface.coffee
+++ app/lib/surface/Surface.coffee
@@ -417,7 +417,7 @@
     @stage.enableMouseOver(10)
     @stage.addEventListener 'stagemousemove', @onMouseMove
     @stage.addEventListener 'stagemousedown', @onMouseDown
-    @stage.addEventListener 'stagemouseup', @onMouseUp
+    @canvas[0].addEventListener 'mouseup', @onMouseUp
     @canvas.on 'mousewheel', @onMouseWheel
     @hookUpChooseControls() if @options.choosing
     createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED


limit newsfeed number [deploy: production]

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/domjtalbot/Portfolio.git/'


Use own promise methods when extending to file API

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/prognostikos/uploadcare-widget.git/'


[worker][social][model][graph] optimized the queries

--- workers/social/lib/social/models/graph/graph.coffee
+++ workers/social/lib/social/models/graph/graph.coffee
@@ -79,7 +79,7 @@

   removePrivateContent:(groupId, contents, callback)->
     query = """
-      start  kd=node:koding(id={groupId})
+      start  kd=node:koding("id:#{groupId}")
       MATCH  kd-[:member]->users-[r:owner]-groups
       WHERE groups.name = "JGroup"
        AND ( groups.privacy = "private"
@@ -87,9 +87,8 @@
       RETURN groups
       ORDER BY r.createdAtEpoch DESC
     """
-    params =
-      groupId   : groupId
-    @db.query query, params, (err, results)=>
+
+    @db.query query, {}, (err, results)=>
       if err then return callback err
       secretGroups = (result.groups.data.slug for result in results)
       filteredContent = []
@@ -102,34 +101,24 @@
     start = new Date().getTime()
     # do not remove white-spaces
     query = """
-        START koding=node:koding(id={groupId})
+        START koding=node:koding("id:#{groupId}")
         MATCH koding-[:member]->members<-[:author]-content
-        WHERE (content.name = "JTutorial"
-         or content.name = "JCodeSnip"
-         or content.name = "JDiscussion"
-         or content.name = "JBlogPost"
-         or content.name = "JStatusUpdate")
-         and has(content.`meta.createdAtEpoch`)
-         and content.`meta.createdAtEpoch` < {startDate}
-         and content.isLowQuality! is null
+        WHERE content.`meta.createdAtEpoch` < #{startDate}
+         and content.isLowQuality? = "false"

       """
     if groupName isnt "koding"
       query += """
-          and has(content.group)
-          and content.group = "#{groupName}"
+          and content.group! = "#{groupName}"
         """
     query += """
         return *
         order by content.`meta.createdAtEpoch` DESC
         limit 20
       """
-
-    params =
-      groupId   : groupId
-      startDate : startDate
-
-    @db.query query, params, (err, results)=>
+    console.log query
+
+    @db.query query, {}, (err, results)=>
       tempRes = []
       if err then callback err
       else if results.length is 0 then callback null, []
@@ -149,6 +138,7 @@
           if groupName == "koding"
             @removePrivateContent  groupId, tempRes, callback
           else
+            console.log tempRes.length()
             callback null, tempRes
         resultData = ( result.content.data for result in results)
         objectify resultData, (objecteds)->
@@ -157,13 +147,12 @@
             collectRelations objected

   fecthRelatedItems:(itemId, callback)->
-    query = [
-      'start koding=node:koding(id={itemId})'
-      'match koding-[r]-all'
-      'where has(koding.`meta.createdAtEpoch`)'
-      'return *'
-      'order by koding.`meta.createdAtEpoch` DESC'
-    ].join('\n');
+    query = """
+      start koding=node:koding("id:#{itemId}")
+      match koding-[r]-all
+      return *
+      order by koding.`meta.createdAtEpoch` DESC
+    """

     params =
       itemId : itemId
@@ -189,21 +178,17 @@
   fetchNewInstalledApps:(group, startDate, callback)->
     {groupId} = group

-    query = [
-      'START kd=node:koding(id={groupId})'
-      'MATCH kd-[:member]->users<-[r:user]-koding'
-      'WHERE koding.name="JApp"'
-      'and r.createdAtEpoch < {startDate}'
-      'return *'
-      'order by r.createdAtEpoch DESC'
-      'limit 20'
-    ].join('\n');
-
-    params =
-      groupId   : groupId
-      startDate : startDate
-
-    @db.query query, params, (err, results) =>
+    query = """
+      START kd=node:koding("id:#{groupId}")
+      MATCH kd-[:member]->users<-[r:user]-koding
+      WHERE koding.name="JApp"
+      and r.createdAtEpoch < #{startDate}
+      return *
+      order by r.createdAtEpoch DESC
+      limit 20
+      """
+
+    @db.query query, {}, (err, results) =>
       if err then throw err
       @generateInstalledApps [], results, callback

@@ -224,21 +209,16 @@
   fetchNewMembers:(group, startDate, callback)->
     {groupId} = group

-    query = [
-      'start  koding=node:koding(id={groupId})'
-      'MATCH  koding-[r:member]->members'
-      'where  members.name="JAccount"'
-      'and r.createdAtEpoch < {startDate}'
-      'return members'
-      'order by r.createdAtEpoch DESC'
-      'limit 20'
-    ].join('\n');
-
-    params =
-      groupId   : groupId
-      startDate : startDate
-
-    @db.query query, params, (err, results) ->
+    query = """
+      start  koding=node:koding("id:#{groupId}")
+      MATCH  koding-[r:member]->members
+      where  members.name="JAccount"
+      and r.createdAtEpoch < #{startDate}
+      return members
+      order by r.createdAtEpoch DESC
+      limit 20
+      """
+    @db.query query, {}, (err, results) ->
         if err then throw err
         resultData = []
         for result in results
@@ -249,48 +229,39 @@
           callback err, objected

   fetchMemberFollows:(group, startDate, callback)->
+    {groupId, groupName} = group
     #followers
-    query = [
-      'start koding=node:koding(id={groupId})'
-      'MATCH koding-[:member]->followees<-[r:follower]-follower'
-      'where followees.name="JAccount"'
-      'and follower.name="JAccount"'
-      'and r.createdAtEpoch < {startDate}'
-      'return r,followees, follower'
-      'order by r.createdAtEpoch DESC'
-      'limit 20'
-    ].join('\n');
-
-    @fetchFollows query, group, startDate, callback
+    query = """
+      start koding=node:koding("id:#{groupId}")
+      MATCH koding-[:member]->followees<-[r:follower]-follower
+      where followees.name="JAccount"
+      and follower.name="JAccount"
+      and r.createdAtEpoch < #{startDate}
+      return r,followees, follower
+      order by r.createdAtEpoch DESC
+      limit 20
+    """
+    @fetchFollows query, callback

   fetchTagFollows:(group, startDate, callback)->
     #followers
-    {groupName} = group
-    query = [
-      'start koding=node:koding(id={groupId})'
-      'MATCH koding-[:member]->followees<-[r:follower]-follower'
-      'where followees.name="JAccount"'
-      'and follower.name="JTag"'
-      'and follower.name="' + groupName + '"'
-      'and r.createdAtEpoch < {startDate}'
-      'return r,followees, follower'
-      'order by r.createdAtEpoch DESC'
-      'limit 20'
-    ].join('\n');
-
-    @fetchFollows query, group, startDate, callback
-
-  fetchFollows:(query, group, startDate, callback)->
-
-
-    {groupId} = group
-
-
-    params =
-      groupId   : groupId
-      startDate : startDate
-
-    @db.query query, params, (err, results)=>
+    {groupId, groupName} = group
+    query = """
+      start koding=node:koding("id:#{groupId}")
+      MATCH koding-[:member]->followees<-[r:follower]-follower
+      where followees.name="JAccount"
+      and follower.name="JTag"
+      and follower.name="#{groupName}"
+      and r.createdAtEpoch < #{startDate}
+      return r,followees, follower
+      order by r.createdAtEpoch DESC
+      limit 20
+      """
+    @fetchFollows query, callback
+
+  fetchFollows:(query, callback)->
+
+    @db.query query, {}, (err, results)=>
       if err then throw err
       @generateFollows [], results, callback


JGroup::sendNotification: code tidy up, callback is optional


activity feed: fix bug where koding new member bucket updates even for other groups


model/group: check user password before delete team

--- workers/social/lib/social/models/group/index.coffee
+++ workers/social/lib/social/models/group/index.coffee
@@ -1552,6 +1552,20 @@
       if err then callback err
       else oldAddOwner.call this, target, options, callback

+
+  checkUserPassword: (account, password, callback) ->
+
+    unless account or password
+      return callback 'Error occured while deleting team'
+
+    account.fetchUser (err, user) =>
+      unless err
+        unless user.checkPassword password
+          return callback 'Your password didn\'t match with our records'
+        else
+          callback()
+
+
   destroy    : permit
     advanced : [
       { permission: 'edit own groups', validateWith : Validators.own }
@@ -1560,12 +1574,15 @@
     success  : (client, password, callback) ->

       JName = require '../name'
+      account = client?.connection?.delegate

       removeHelper = (model, err, next) ->
         return next err  if err
         return next()  unless model
+      @checkUserPassword account, password, (err) =>

         model.remove (err) -> next err
+        return callback new KodingError err  if err

       removeHelperMany = (klass, models, err, next) ->
         return next err  if err


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

error: pathspec 'src/camera_fade.coffee' did not match any file(s) known to git

--- src/camera_fade.coffee
+++ src/camera_fade.coffee
@@ -0,0 +1,57 @@
+###*
+The Fade module provides convenience methods for accessing common Engine.Flash presets.
+
+@name Fade
+@fieldOf Camera
+@module
+@param {Object} I Instance variables
+@param {Object} self Reference to the engine
+@see Camera.Flash
+###
+Camera.Fade = (I, self) ->
+  configureFade = (duration, color, alpha) ->
+    I.flashDuration = duration
+    I.flashCooldown = duration
+    I.flashColor = Color(color)
+    I.flashTargetAlpha = alpha
+
+  ###*
+  A convenient way to set the flash effect instance variables. This provides a shorthand for fading the screen in
+  from a given color over a specified duration.
+
+

+  engine.fadeIn()
+  # => Sets the effect variables to their default state. This will the screen to go from black to transparent over the next 30 frames.
+
+  engine.fadeIn('blue', 50)
+  # => This effect will start off blue and fade to transparent over 50 frames.
+

+
+  @name fadeIn
+  @methodOf Camera#
+  @param {Number} [duration=30] How long the effect lasts
+  @param {Color} [color="black"] The color to fade from
+  ###
+  fadeIn: (duration = 30, color = 'black') ->
+    configureFade(duration, color, 0)
+
+  ###*
+  A convenient way to set the flash effect instance variables. This provides a shorthand for fading
+  the screen to a given color over a specified duration.
+
+

+  camera.fadeOut()
+  # => Sets the effect variables to their default state. This will the screen to fade from ransparent to black over the next 30 frames.
+
+  camera.fadeOut('blue', 50)
+  # => This effect will start off transparent and change to blue over 50 frames.
+

+
+  @name fadeOut
+  @methodOf Camera#
+  @param {Number} [duration=30] How long the effect lasts
+  @param {Color} [color="transparent"] The color to fade to
+  ###
+  fadeOut: (duration = 30, color = 'transparent') ->
+    configureFade(duration, color, 1)
+


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

error: pathspec 'src/camera_zoom.coffee' did not match any file(s) known to git

--- src/camera_zoom.coffee
+++ src/camera_zoom.coffee
@@ -0,0 +1,23 @@
+Camera.Zoom = (I, self) ->
+  Object.reverseMerge I,
+    maxZoom: 10
+    minZoom: 0.1
+    zoom: 1
+
+  clampZoom = (value) ->
+    value.clamp(I.minZoom, I.maxZoom)
+
+  zoomIn: (percentage) ->
+    self.zoom clampZoom(I.zoom * (1 + percentage))
+
+  zoomOut: (percentage) ->
+    self.zoom clampZoom(I.zoom * (1 - percentage))
+
+  zoom: (value) ->
+    if value?
+      I.zoom = clampZoom(value)
+
+      return self
+    else
+      return I.zoom
+


Abstracted a nav__submenu__item class

Abstracted a nav__submenu__item class

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/lonelyplanet/rizzo.git/'


Fixed naive coffeescript bug

Fixed naive coffeescript bug

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/sightmachine/treema.git/'


Tweak to handle when all the children in a newly created object node are hidden.


diff-2-html module

diff-2-html module

error: pathspec 'src/diff.coffee' did not match any file(s) known to git

--- src/diff.coffee
+++ src/diff.coffee
@@ -0,0 +1,50 @@
+# test parsing xml
+
+fs = require 'fs'
+difflet = require 'difflet'
+ent = require 'ent'
+
+load = require './loader.coffee'
+node = require './nodes.coffee'
+
+module.exports = (f1, f2) ->
+  prev = node.build load f1
+  next = node.build load f2
+
+  tags =
+    inserted: ''
+    updated: ''
+    deleted: ''
+    comment: ''
+
+  page = """
+
+
+
+

+         """
+
+  page += difflet({
+    indent: 2
+    comment: true
+    start: (t, s) ->
+      s.write tags[t]
+    stop: (t, s) ->
+      s.write ''
+    write: (buf, s) ->
+      s.write ent.encode buf
+  }).compare(prev, next)
+
+  page += """
+

+
+
+          """
+
+  page


:new: Add Plus file

:new: Add Plus file

error: pathspec 'lib/plus.coffee' did not match any file(s) known to git

--- lib/plus.coffee
+++ lib/plus.coffee
@@ -0,0 +1,37 @@
+
+
+{CompositeDisposable} = require('atom')
+
+class LinterPlus
+  Subscriptions: null
+  InProgress: false
+  Linters: []
+  constructor:->
+    @Subscriptions = new CompositeDisposable
+    @Subscriptions.add atom.workspace.observeTextEditors (editor)=>
+      return if @InProgress
+      editor.onDidSave(@lint.bind(@))
+  lint:->
+    @InProgress = true
+
+    ActiveEditor = atom.workspace.getActiveEditor()
+    Buffer = ActiveEditor.getBuffer()
+    return unless ActiveEditor
+    Scopes = ActiveEditor.scopeDescriptorForBufferPosition(ActiveEditor.getCursorBufferPosition()).scopes
+    Promises = []
+    @Linters.forEach (Linter)->
+      Matching = Scopes.filter (Entry)-> Linter.scopes.indexOf(Entry) isnt -1
+      return unless Matching.length
+      RetVal = Linter.lint(ActiveEditor, Buffer)
+      if RetVal instanceof Promise
+        Promises.push RetVal
+      else if RetVal
+        Promises.push RetVal
+    Promise.all(Promises).then =>
+      @InProgress = false
+    , =>
+      @InProgress = false
+  deactivate:->
+    @Subscriptions.dispose()
+
+module.exports = LinterPlus


Match `RequestsPending:parse` to API changes (Resolves #81)

--- SingularityUI/app/collections/RequestsPending.coffee
+++ SingularityUI/app/collections/RequestsPending.coffee
@@ -6,9 +6,9 @@

     parse: (requests) ->
         _.each requests, (request, i) =>
-            request.id = request.id
-            request.pendingType = request.pendingType
+            request.id = request.requestId
             request.JSONString = utils.stringJSON request
+            request.timestampHuman = utils.humanTimeAgo request.timestamp
             app.allRequests[request.id] = request

         requests


added community detection algorithm

added community detection algorithm

error: pathspec 'src/network/cluster.coffee' did not match any file(s) known to git

--- src/network/cluster.coffee
+++ src/network/cluster.coffee
@@ -0,0 +1,119 @@
+#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+# Community detection algorithm (graph clustering/partitioning)
+# Based on the paper:
+# Finding community structure in very large networks, A Clauset, MEJ Newman, C Moore - Physical review E, 2004
+#------------------------------------------------------------------------------
+
+# edges; a list of edge objects
+
+# options; a dictionary of options with attributes
+    # distance; it can be:
+      # undefined; every edge has default distance of 1
+      # constant; every edge has the same distance
+      # string; the name of the attribute in edge that describes the distance of that edge
+      # array; each value corresponds to the distance of the respective edge in the edges array
+      # function; given edge, returns the distance
+
+    # nodeid; it can be:
+      # undefined; then we assume that each node obtained by getting the endpoints of an edge is a string/number describing the id of the node
+      # string; the name of the attribute in node that describes the id of the node.
+      # function; given the node, returns the id.
+
+    # startpoint; it can be:
+      # undefined; it is assumed that edge.source points to the source of the edge
+      # string; the name of the attribute in edge pointing to the source of the edge
+      # function; given an edge returns the source node of that edge
+
+    # endpoint; it can be:
+      # undefined; it is assumed that edge.target points to the target of the edge
+      # string; the name of the attribute in edge pointing to the target of the edge
+      # function; given an edge returns the target node of that edge
+
+    # nodes; if defined, the input is assumed to be normalized and nodes is assumed to be a dictionary
+    # that maps node id to the outedges of the node
+
+# returns an array of communities, where each community is an array of node ids belonging to that community.
+
+d3plus.network.cluster = (edges, options) ->
+    ######### User's options normalization ############
+    if not options? then options = {}
+    if not options.nodes? or typeof options.nodes isnt 'object'
+      [edges, options] = d3plus.network.normalize edges, options
+      if options is null then return null
+    # unpack options object
+    {distance, nodeid, startpoint, endpoint, nodes} = options
+    ####### END user's input normalization #########
+
+    # build the nodes map, which stores the degree of every node
+    nodesMap = {}
+    for id of nodes
+      nodesMap[id] = { node: nodes[id].node, degree:0 }
+
+    # build the links map, which stores the expected number of links between every pair of nodes
+    m = 0
+    linksMap = {}
+    for edge in edges
+      a = nodeid startpoint edge
+      b = nodeid endpoint edge
+      linksMap[a] = {} if a not of linksMap
+      linksMap[b] = {} if b not of linksMap
+
+      if b not of linksMap[a]
+        linksMap[a][b] = 0
+        linksMap[b][a] = 0
+        m++
+        nodesMap[a].degree+=1
+        nodesMap[b].degree+=1
+
+
+    communities = {}
+    Q = 0
+    for id, node of nodesMap
+      communities[id] = {score: node.degree / (2.0*m), nodes:[id]}
+
+    for a of linksMap
+      for b of linksMap[a]
+        linksMap[a][b] = 1.0 / (2*m) - (nodesMap[a].degree * nodesMap[b].degree)/(4.0*m*m)
+
+    iter = 0
+    while iter < 1000
+      ## find largest element of links
+      deltaQ = -1
+      maxa = undefined
+      maxb = undefined
+      for a of linksMap
+        for b of linksMap[a]
+          if linksMap[a][b] > deltaQ
+            deltaQ = linksMap[a][b]
+            maxa = a
+            maxb = b
+      break if deltaQ < 0
+      ## merge maxa into maxb
+      for k of linksMap[maxa]
+        if k isnt maxb
+          if k of linksMap[maxb]
+            ## k is connected to both a and b
+            linksMap[maxb][k] += linksMap[maxa][k]
+          else
+            ## k is connected to a but not b
+            linksMap[maxb][k] = linksMap[maxa][k] - 2*communities[maxb].score*communities[k].score
+          linksMap[k][maxb] = linksMap[maxb][k]
+        delete linksMap[k][maxa]
+      for k of linksMap[maxb]
+        if k not of linksMap[maxa] and  k isnt maxb
+          ## k is connected to b but not a
+          linksMap[maxb][k] -= 2*communities[maxa].score*communities[k].score
+          linksMap[k][maxb] = linksMap[maxb][k]
+
+      for node in communities[maxa].nodes
+        communities[maxb].nodes.push node
+      communities[maxb].score += communities[maxa].score
+      delete communities[maxa]
+      delete linksMap[maxa]
+      Q += deltaQ
+      iter++
+
+    ## sort communities by size
+    commSizes = ([cid, community.nodes.length] for cid, community of communities)
+    commSizes.sort (a,b) -> b[1] - a[1]
+    communities[commSize[0]].nodes for commSize in commSizes


bugfix: bestOfYourTown acquire_coupon middleware

 On branch master

	modified:   bestofyourtown/acquire_coupon.coffee

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/FireworksProject/platform.y.git/'


oauth: unlink on user deletion

oauth: unlink on user deletion

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/andrewjcasal/koding.git/'


refactored updateAccountInfo and createDefaultStackForKodingGroup functions

--- workers/social/lib/social/models/user/index.coffee
+++ workers/social/lib/social/models/user/index.coffee
@@ -1334,34 +1334,34 @@
     daisy queue

-  updateAccountInfo = (options, queue, callback) ->
+  updateAccountInfo = (options, callback) ->

     { account, referrer, username } = options

-    _queue = [
+    queue = [

       ->
         account.update { $set: { type: 'registered' } }, (err) ->
           return callback err  if err?
-          _queue.next()
+          queue.next()

       ->
         account.createSocialApiId (err) ->
           return callback err  if err
-          _queue.next()
+          queue.next()

       ->
         # setting referrer
-        return _queue.next()  unless referrer
+        return queue.next()  unless referrer

         if username is referrer
           console.error "User (#{username}) tried to refer themself."
-          return _queue.next()
+          return queue.next()

         JUser.count { username: referrer }, (err, count) ->
           if err? or count < 1
             console.error 'Provided referrer not valid:', err
-            return _queue.next()
+            return queue.next()

           account.update { $set: { referrerUsername: referrer } }, (err) ->

@@ -1369,16 +1369,17 @@
             then console.error err
             else console.log "#{referrer} referred #{username}"

-            _queue.next()
-
-      -> queue.next()
+            queue.next()
+
+      ->
+        return callback null

     ]

-    daisy _queue
-
-
-  createDefaultStackForKodingGroup = (options, queue) ->
+    daisy queue
+
+
+  createDefaultStackForKodingGroup = (options, callback) ->

     { account } = options

@@ -1398,7 +1399,7 @@
       # We are not returning error here on purpose, even stack template
       # not created for a user we don't want to break registration process
       # at all ~ GG
-      queue.next()
+      callback null

   confirmAccountIfNeeded = (options, callback) ->
@@ -1501,7 +1502,9 @@
           queue.next()

       ->
-        updateAccountInfo { account, referrer, username }, queue, callback
+        updateAccountInfo { account, referrer, username }, (err) ->
+          return callback err  if err
+          queue.next()

       =>
         groupNames = [client.context.group, 'koding']
@@ -1511,7 +1514,9 @@
           queue.next()

       ->
-        createDefaultStackForKodingGroup { account }, queue
+        createDefaultStackForKodingGroup { account }, (err) ->
+          return callback err  if err
+          queue.next()

       ->
         user.setPassword password, (err) ->


handle correctly querystring when passing as string and not as object

--- packages/rocketchat-oembed/server/providers.coffee
+++ packages/rocketchat-oembed/server/providers.coffee
@@ -1,4 +1,5 @@
 URL = Npm.require('url')
+QueryString = Npm.require('querystring')

 class Providers
 	providers: []
@@ -57,13 +58,17 @@
 			data.requestOptions.path = consumerUrl.path

 RocketChat.callbacks.add 'oembed:afterParseContent', (data) ->
-	if data.parsedUrl?.query?.url?
-		url = data.parsedUrl.query.url
-		provider = providers.getProviderForUrl url
-		if provider?
-			if data.content?.body?
-				metas = JSON.parse data.content.body;
-				_.each metas, (value, key) ->
-					if _.isString value
-						data.meta[changeCase.camelCase('oembed_' + key)] = value
-				data.meta['oembedUrl'] = url
+	if data.parsedUrl?.query?
+		queryString = data.parsedUrl.query
+		if _.isString data.parsedUrl.query
+			queryString = QueryString.parse data.parsedUrl.query
+		if queryString.url?
+			url = queryString.url
+			provider = providers.getProviderForUrl url
+			if provider?
+				if data.content?.body?
+					metas = JSON.parse data.content.body;
+					_.each metas, (value, key) ->
+						if _.isString value
+							data.meta[changeCase.camelCase('oembed_' + key)] = value
+					data.meta['oembedUrl'] = url


Include release stage in campfire notification

--- plugins/campfire/index.coffee
+++ plugins/campfire/index.coffee
@@ -3,7 +3,7 @@
 class Campfire extends NotificationPlugin
   @receiveEvent: (config, event, callback) ->
     # Build the message
-    message = "#{event.trigger.message} in #{event.project.name}!"
+    message = "#{event.trigger.message} in #{event.error.releaseStage} from #{event.project.name}!"
     if event.error
       message += " #{event.error.exceptionClass}" if event.error.exceptionClass
       message += ": #{event.error.message}" if event.error.message


Make sure username exists in findByActiveUsersExcept (#6674)

--- packages/rocketchat-lib/server/models/Users.coffee
+++ packages/rocketchat-lib/server/models/Users.coffee
@@ -130,7 +130,7 @@
 					]
 				}
 				{
-					username: { $nin: exceptions }
+					username: { $exists: true, $nin: exceptions }
 				}
 			]


fix(Dataset configuration): decimal data size 12,2 by default

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/keboola/kbc-ui-gooddata-writer.git/'


Client: TeamSettings: Members: Deleted unnecessary parameters

--- client/admin/lib/views/members/adminmembersview.coffee
+++ client/admin/lib/views/members/adminmembersview.coffee
@@ -31,25 +31,19 @@
     all.addSubView @allView = new TeamMembersCommonView
       fetcherMethod          : 'fetchMembersWithEmail'
       showSearchFieldAtFirst : yes
-      noItemFoundWidget      : new kd.CustomHTMLView
-        partial              : 'No members found!'
-        cssClass             : 'no-item-view hidden'
+      noItemFoundText        : 'No members found!'
     , data

     admins.addSubView @adminsView = new TeamMembersCommonView
       fetcherMethod     : 'fetchAdminsWithEmail'
       defaultMemberRole : 'admin'
-      noItemFoundWidget : new kd.CustomHTMLView
-        partial         : 'No admins found!'
-        cssClass        : 'no-item-view'
+      noItemFoundText   : 'No admins found!'
     , data

     mods.addSubView @modsView = new TeamMembersCommonView
       fetcherMethod     : 'fetchModeratorsWithEmail'
       defaultMemberRole : 'moderator'
-      noItemFoundWidget : new kd.CustomHTMLView
-        partial         : 'No moderators found!'
-        cssClass        : 'no-item-view'
+      noItemFoundText   : 'No moderators found!'
     , data

@@ -59,9 +53,7 @@
       blocked.addSubView @blockedView = new TeamMembersCommonView
         fetcherMethod     : 'fetchBlockedAccountsWithEmail'
         listViewItemClass : BlockedMemberItemView
-        noItemFoundWidget : new kd.CustomHTMLView
-          partial         : 'No disabled user found!'
-          cssClass        : 'no-item-view'
+        noItemFoundText   : 'No disabled user found!'
       , data

       @blockedView.listController.getListView().on 'ItemWasAdded', (item) =>


Removed hardcoded substract value at _windowDidResize method of MainTabHandler.


protect against empty values

protect against empty values

--- app/assets/javascripts/core.js.coffee
+++ app/assets/javascripts/core.js.coffee
@@ -418,11 +418,12 @@
   ###
   values: ->
     values = []
-    for value in @json['values']
-      if value['scalar']?
-        values.push new hQuery.PhysicalQuantity value
-      else
-        values.push hQuery.createCodedValues values
+    if @json['values']
+      for value in @json['values']
+        if value['scalar']?
+          values.push new hQuery.PhysicalQuantity value
+        else
+          values.push hQuery.createCodedValues values
     values


fix(run tde export): prepend config tag with 'config-'

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/keboola/kbc-ui-tde-exporter.git/'


Fixed the camera share email template bug. (#2133)

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/evercam/evercam-dashboard.git/'


assign debug to console.* functions, that way the file/line numbers are more sane in the developer console

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/joeroback/atom-clang.git/'


fixing the login redirect

fixing the login redirect

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/Mikuia/Mikuia.git/'


also delete selection on insert.

also delete selection on insert.

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/robey/carrot16.git/'


fix for show/hide pagination [#97186346]

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/netguru/review.git/'


Fix to prevent this.userId error while making saveUser call

--- packages/rocketchat-api/server/routes.coffee
+++ packages/rocketchat-api/server/routes.coffee
@@ -245,7 +245,8 @@

 			userData = _.extend({ _id: @bodyParams.userId }, @bodyParams.data)

-			RocketChat.saveUser(@userId, userData)
+			Meteor.runAsUser @userId, =>
+				RocketChat.saveUser(@bodyParams.userId, userData)

 			if @bodyParams.data.customFields?
 				RocketChat.saveCustomFields(@bodyParams.userId, @bodyParams.data.customFields)
@@ -281,7 +282,7 @@
 			if not RocketChat.authz.hasPermission(@userId, 'delete-user')
 				return RocketChat.API.v1.unauthorized()

-			Meteor.runAsUser this.userId, =>
+			Meteor.runAsUser @userId, =>
 				id = Meteor.call 'deleteUser', @bodyParams.userId, []

 		catch e


added test file for verifyslug.coffee

added test file for verifyslug.coffee

error: pathspec 'servers/lib/server/handlers/verifyslug.test.coffee' did not match any file(s) known to git

--- servers/lib/server/handlers/verifyslug.test.coffee
+++ servers/lib/server/handlers/verifyslug.test.coffee
@@ -0,0 +1,162 @@
+Bongo                                     = require 'bongo'
+request                                   = require 'request'
+
+{ daisy }                                 = Bongo
+{ expect }                                = require 'chai'
+
+{ TeamHandlerHelper
+  generateRandomString }                  = require '../../../testhelper'
+{ generateVerifySlugRequestParams }       = require '../../../testhelper/verifyslughandlerhelper.coffee'
+{ generateCreateTeamRequestParams }       = TeamHandlerHelper
+
+
+runTests = -> describe 'server.handlers.verifyslug', ->
+
+  it 'should send HTTP 404 if request method is not POST', (done) ->
+
+    queue       = []
+    methods     = ['put', 'patch', 'delete']
+
+    methods.forEach (method) ->
+      verifySlugRequestParams = generateVerifySlugRequestParams
+        method  : method
+        body    :
+          name  : 'some-domain'
+
+      queue.push ->
+        request verifySlugRequestParams, (err, res, body) ->
+          expect(err)             .to.not.exist
+          expect(res.statusCode)  .to.be.equal 404
+          queue.next()
+
+    queue.push -> done()
+
+    daisy queue
+
+
+  describe 'when team domain is not set', ->
+
+    it 'should send HTTP 400 if team domain is not set', (done) ->
+
+      verifySlugRequestParams = generateVerifySlugRequestParams
+        body   :
+          name : ''
+
+      request.post  verifySlugRequestParams, (err, res, body) ->
+        expect(err)             .to.not.exist
+        expect(res.statusCode)  .to.be.equal 400
+        expect(body)            .to.be.equal 'No domain param is given!'
+        done()
+
+
+  describe 'when team name is not valid', ->
+
+    it 'should send HTTP 400 if team domain contains invalid characters', (done) ->
+
+      queue = []
+      invalidTeamDomains = [
+        '-'
+        '-domain'
+        'domain-'
+        '(domain'
+        '!domain'
+        '#domain'
+        'domain@'
+        'domain%'
+        'domain?'
+        'domain☺'
+        'domainCamelCase'
+        'domain.with.dots'
+        'domain with whitespaces'
+      ]
+
+      invalidTeamDomains.forEach (invalidTeamDomain) ->
+        verifySlugRequestParams = generateVerifySlugRequestParams
+          body   :
+            name : invalidTeamDomain
+
+        queue.push ->
+          request.post verifySlugRequestParams, (err, res, body) ->
+            expect(err)             .to.not.exist
+            expect(res.statusCode)  .to.be.equal 400
+            expect(body)            .to.be.equal 'Invalid domain!'
+            queue.next()
+
+      queue.push -> done()
+
+      daisy queue
+
+  describe 'when domain is available', ->
+
+    it 'should send HTTP 200 if domain is valid', (done) ->
+
+      queue = []
+      validTeamDomains = [
+        'validdomain'
+        'valid-domain'
+        'valid-domain2'
+        'valid-domain-2'
+        '3valid-domain'
+        '3-valid-domain'
+        'valid4-domain'
+        'valid-4-domain'
+      ]
+
+      validTeamDomains.forEach (validTeamDomain) ->
+        verifySlugRequestParams = generateVerifySlugRequestParams
+          body   :
+            name : validTeamDomain
+
+        queue.push ->
+          request.post verifySlugRequestParams, (err, res, body) ->
+            expect(err)             .to.not.exist
+            expect(res.statusCode)  .to.be.equal 200
+            expect(body)            .to.be.equal 'Domain is available!'
+            queue.next()
+
+      queue.push -> done()
+
+      daisy queue
+
+
+  describe 'when domain is taken', ->
+
+    it 'should send http 400', (done) ->
+
+      slug = generateRandomString()
+
+      createTeamRequestParams = generateCreateTeamRequestParams
+        body   :
+          slug : slug
+
+      verifySlugRequestParams = generateVerifySlugRequestParams
+        body   :
+          name : slug
+
+      queue = [
+
+        ->
+          # expecting team to be created
+          request.post createTeamRequestParams, (err, res, body) ->
+            expect(err)             .to.not.exist
+            expect(res.statusCode)  .to.be.equal 200
+            queue.next()
+
+        ->
+          # expecting HTTP 400 when domain is taken
+          request.post verifySlugRequestParams, (err, res, body) ->
+            expect(err)             .to.not.exist
+            expect(res.statusCode)  .to.be.equal 400
+            expect(body)            .to.be.equal 'Domain is taken!'
+            queue.next()
+
+        -> done()
+
+      ]
+
+      daisy queue
+
+
+runTests()
+
+


[web] [fix] update GH repo name

[web] [fix] update GH repo name


fix(index): click on button "create first orchestration"

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/keboola/kbc-ui-orchestrators.git/'


tableverse/avatar: Initial avatar support.

error: pathspec 'Oghma/tableverse/avatar.coffee' did not match any file(s) known to git

--- Oghma/tableverse/avatar.coffee
+++ Oghma/tableverse/avatar.coffee
@@ -0,0 +1,191 @@
+# Copyright 2010-2013 Christopher Alfeld
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+Oghma = @Oghma ?= {}
+Oghma.Thingy ?= {}
+
+# Layer for avatar.
+c_layer       = 'avatars'
+
+# Local data to tell set to not redraw.
+c_no_redraw = 'no_redraw'
+
+Oghma.Thingy.Tableverse.register( ( thingyverse, O ) ->
+  thingyverse.avatar = new Heron.Index.MapIndex(
+    'owner',
+    'name',
+    'category',
+    'group'
+  )
+
+  draw_layer = ->
+    O.layer[ c_layer ].draw()
+
+  show_labels = ->
+    thingyverse.avatar.each( ( avatar ) ->
+      avatar.show_label()
+    )
+  hide_labels = ->
+    thingyverse.avatar.each( ( avatar ) ->
+      avatar.hide_label()
+    )
+
+  thingyverse.define(
+    'avatar',
+    [
+      'font_size',
+      'r',
+      'owner',
+      'name',
+      'index',
+      'group',
+      'category',
+      'fill', 'stroke',
+      'token'
+    ],
+    {
+      vis: ['visible_to' ]
+      loc: [ 'x', 'y' ]
+    },
+    ( attrs ) ->
+      @__ =
+        x:          attrs.x          ? 0
+        y:          attrs.y          ? 0
+        font_size:  attrs.font_size  ? 12
+        r:          attrs.r          ? O.current_table.g2k(1)
+        owner:      attrs.owner      ? O.me().gets( 'name' )
+        name:       attrs.name       ? ''
+        index:      attrs.index      ? ''
+        group:      attrs.group      ? 'undetermined'
+        category:   attrs.category   ? 'undetermined'
+        fill:       attrs.color1     ? O.me().gets( 'primary' )
+        stroke:     attrs.color2     ? O.me().gets( 'secondary' )
+        token:      attrs.token      ? ''
+        visible_to: attrs.visible_to ? []
+
+      @after_construction( ->
+        thingyverse.avatar.add( this )
+      )
+
+      @is_owned = =>
+        O.me().gets('name') == @__.owner
+
+      @is_visible = =>
+        @__.visible_to.length == 0 ||
+        @__.visible_to.indexOf( O.me().gets( 'name' ) ) != -1
+
+      @show_label = =>
+        if @is_visible() && @__k?
+          tween = new Kinetic.Tween(
+            node:     @__klabel,
+            duration: 0.25,
+            opacity:  1
+          )
+          tween.play()
+      @hide_label = =>
+        if @is_visible() && @__k?
+          tween = new Kinetic.Tween(
+            node:     @__klabel,
+            duration: 0.25,
+            opacity:  0
+          )
+          tween.play()
+
+      @__redraw = =>
+        @__k.destroy() if @__k?
+        if @is_visible()
+          @__k = new Kinetic.Group(
+            x: @__.x
+            y: @__.y
+          )
+          @__kdisk = new Kinetic.Circle(
+            radius:    @__.r
+            fill:      @__.fill
+            stroke:    @__.stroke
+          )
+          @__klabel = new Kinetic.Text(
+            text:     @__.name + if @__.index? then ' ' + @__.index else ''
+            align:    'center'
+            y:        -1 * @__.r - @__.font_size
+            fill:     @__.stroke
+            stroke:   null
+            fontSize: @__.font_size
+            opacity:  0
+          )
+          @__klabel.setOffset( x: @__klabel.getWidth() / 2  )
+          @__k.add( @__kdisk )
+          @__k.add( @__klabel )
+
+          @__kdisk.on( 'click', ( e ) =>
+            if e.which == 3 && ( @is_owned() || e.shiftKey )
+              items = [
+                {
+                  text: 'Remove'
+                  handler: => @remove()
+                }
+              ]
+              if O.isGM()
+                items.push('-')
+                items = items.concat( Oghma.SubMenu.visibility( O, this ) )
+              menu = Ext.create( 'Oghma.Ext.Menu', items: items )
+              e.stopPropagation()
+              menu.showAt( [ e.pageX, e.pageY ] )
+          )
+
+          @__k.on( 'mousedown', ( e ) =>
+            if @is_owned() || e.shiftKey
+              @__k.setDraggable(true)
+          )
+          @__k.on( 'dragend', ( e ) =>
+            @__k.setDraggable(false)
+            @set( @__k.getPosition(), c_no_redraw )
+          )
+
+          @__kdisk.on( 'mouseenter', show_labels )
+          @__kdisk.on( 'mouseleave', hide_labels )
+
+          O.layer[ c_layer ].add( @__k )
+
+      @__redraw()
+      draw_layer()
+
+      set: (thingy, attrs, local_data) ->
+        need_redraw = false
+        for k, v of attrs
+          if v != thingy.__[k]
+            thingy.__[k] = v
+            need_redraw = true
+        if need_redraw && local_data != c_no_redraw
+          thingy.__redraw()
+          draw_layer()
+
+        null
+
+      get: ( thingy, keys... ) ->
+        thingy.__
+
+      remove: ( thingy ) ->
+        thingyverse.avatar.remove( thingy )
+        thingy.__k.destroy()
+        draw_layer()
+        null
+    )
+
+  O.ui_colors.on_set( ->
+    O.tableverse.avatar.each( ( avatar ) ->
+      avatar.__redraw()
+      draw_layer()
+    )
+  )
+)


Correct search query

Correct search query

--- resources/assets/coffee/react/beatmaps/main.coffee
+++ resources/assets/coffee/react/beatmaps/main.coffee
@@ -95,6 +95,8 @@

   buildSearchQuery: =>
+    return {} if !currentUser.id?
+
     params = _.extend {}, @state.filters

     keyToChar = _.invert BeatmapsetFilter.charToKey
@@ -103,6 +105,8 @@
     for own key, value of params
       if value? && BeatmapsetFilter.defaults[key] != value
         charParams[keyToChar[key]] = value
+
+    delete charParams[keyToChar['rank']] if !currentUser.isSupporter

     charParams


fix [e51d4fc4e9122463b56b65b18f86db3f40afabbd]


Publish builds from this branch to test signing

--- build/tasks/publish-build-task.coffee
+++ build/tasks/publish-build-task.coffee
@@ -19,7 +19,8 @@
   grunt = gruntObject

   grunt.registerTask 'publish-build', 'Publish the built app', ->
-    return if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH isnt 'master'
+    return if process.env.JANKY_SHA1 #and process.env.JANKY_BRANCH isnt 'master'
+    return unless process.platform is 'win32'
     tasks = ['upload-assets']
     tasks.unshift('build-docs', 'prepare-docs') if process.platform is 'darwin'
     grunt.task.run(tasks)


Use util.inspect on details

Use util.inspect on details

--- build/tasks/publish-build-task.coffee
+++ build/tasks/publish-build-task.coffee
@@ -101,7 +101,7 @@
 logError = (message, error, details) ->
   grunt.log.error(message)
   grunt.log.error(error.message ? error) if error?
-  grunt.log.error(details) if details
+  grunt.log.error(require('util').inspect(details)) if details

 zipAssets = (buildDir, assets, callback) ->
   zip = (directory, sourcePath, assetName, callback) ->


Fixed a terrible bug.

Fixed a terrible bug.

--- app/views/editor/component/ThangComponentsEditView.coffee
+++ app/views/editor/component/ThangComponentsEditView.coffee
@@ -25,6 +25,7 @@

   constructor: (options) ->
     super options
+    @originalsLoaded = {}
     @components = options.components or []
     @components = $.extend true, [], @components # just to be sure
     @lastComponentLength = @components.length
@@ -36,6 +37,10 @@

   loadComponents: (components) ->
     for componentRef in components
+      # just to handle if ever somehow the same component is loaded twice, through bad data and alike
+      continue if @originalsLoaded[componentRef.original]
+      @originalsLoaded[componentRef.original] = componentRef.original
+
       levelComponent = new LevelComponent(componentRef)
       url = "/db/level.component/#{componentRef.original}/version/#{componentRef.majorVersion}"
       levelComponent.setURL(url)
@@ -143,7 +148,9 @@
     @reportChanges()

   updateComponentsList: ->
-    @componentsTreema?.set('/', $.extend(true, [], @components))
+    # Before I was setting the data to the existing treema but then we had some
+    # nasty sorting/callback bugs. This is less efficient, but it's also less bug prone.
+    @buildComponentsTreema()

   onComponentsAdded: ->
     return unless @componentsTreema
@@ -157,11 +164,14 @@
       for componentRef in _.values(componentMap)
         componentModel = @supermodel.getModelByOriginalAndMajorVersion(
           LevelComponent, componentRef.original, componentRef.majorVersion)
+        if not componentModel?.loaded
+          @loadComponents([componentRef])
+          continue
         for dependency in componentModel?.get('dependencies') or []
           if not componentMap[dependency.original]
             component = @supermodel.getModelByOriginalAndMajorVersion(
               LevelComponent, dependency.original, dependency.majorVersion)
-            if not component
+            if not component?.loaded
               @loadComponents([dependency])
               # will run onComponentsAdded once more when the model loads
             else
@@ -204,7 +214,7 @@

   makeThangComponentConfigView: (thangComponent) ->
     component = @supermodel.getModelByOriginal(LevelComponent, thangComponent.original)
-    return unless component
+    return unless component?.loaded
     config = thangComponent.config ? {}
     configView = new ThangComponentConfigView({
       supermodel: @supermodel


(- fix) interact: Inspect expr-bassed roots correctly

--- Paws/Source/interactive.coffee
+++ Paws/Source/interactive.coffee
@@ -36,7 +36,7 @@
       inspector = new Native (result)->
          process.stdout.write Paws.inspect(result) + "\n"
       .rename '<interact: inspect result>'
-      @shared_locals.push Thing.pair '<inspect>', inspector
+      @shared_locals.push Thing.pair '_INTERACTIVE_INSPECT', inspector

    prompt: -> @readline.prompt()

@@ -106,14 +106,14 @@

       # We generate a wrapper-Expression for the input, turning it into:
       #
-      #     <inspector> (expr)
+      #     _INTERACTIVE_INSPECT (expr)
       if code instanceof parser.Expression
-         inspector = new parser.Expression new Label '<inspector>'
+         inspector = new parser.Expression new Label '_INTERACTIVE_INSPECT'
          superexpr = new parser.Expression code
          inspector.append superexpr
          expr = inspector
       else
-         expr = parser.parse '<inspect> ['+code+']'
+         expr = parser.parse '_INTERACTIVE_INSPECT ['+code+']'

       Paws.info "-- Generated expression to evaluate: " +
          expr.with(context: yes, tag: no).toString()


Check for bb-page control added.

Check for bb-page control added.

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/Bogdan-p/bookingbug-angular.git/'


stack-editor: use sidebar ctrl to set selected states

Signed-off-by: Umut Sirin <4055abbc0e40a1254e715b952ccd414607e0b365@gmail.com>

--- client/stack-editor/lib/index.coffee
+++ client/stack-editor/lib/index.coffee
@@ -34,9 +34,8 @@
       Object.keys(@shouldReloadMap).forEach @bound 'removeEditor'

-  openEditor: (stackTemplateId = no) ->
+  openEditor: (stackTemplateId = no, stackId) ->
     { mainController, groupsController, computeController } = kd.singletons
-    { setSelectedMachineId, setSelectedTemplateId } = EnvironmentFlux.actions

     unless groupsController.canEditGroup()
       mainController.tellChatlioWidget 'isShown', {}, (err, isShown) ->
@@ -44,11 +43,15 @@
         return if isShown
         mainController.tellChatlioWidget 'show', { expanded: no }

-    setSelectedMachineId null
-
     if stackTemplateId
-      setSelectedTemplateId stackTemplateId
       if @editors[stackTemplateId]
+        { sidebar } = kd.singletons
+
+        sidebar.setSelected
+          templateId: stackTemplateId
+          stackId: stackId
+          machineId: null
+
         return  @showView { _id: stackTemplateId }

       computeController.fetchStackTemplate stackTemplateId, (err, stackTemplate) =>
@@ -58,6 +61,14 @@
           return showError err

         editor = @showView stackTemplate
+
+        { sidebar } = kd.singletons
+
+        sidebar.setSelected
+          templateId: stackTemplateId
+          stackId: stackId
+          machineId: null
+
         # If selected template is deleted, then redirect them to ide.
         # TODO: show an information modal to the user if he/she is admin. ~Umut
         stackTemplate.on 'deleteInstance', =>


Added authorizedUser tests

Added authorizedUser tests

error: pathspec 'tests/jasmine/server/unit/authorizedUserSpec.coffee' did not match any file(s) known to git

--- tests/jasmine/server/unit/authorizedUserSpec.coffee
+++ tests/jasmine/server/unit/authorizedUserSpec.coffee
@@ -0,0 +1,18 @@
+describe "authorizedUser utility function", ->
+
+    it "returns false if called without a userId", ->
+        expect(authorizedUser(null)).toBeFalsy()
+
+    it "returns false if the user does not have admin role", ->
+        userId = 1234
+        spyOn Roles, "userIsInRole"
+            .and.returnValue false
+        expect(authorizedUser(userId)).toBeFalsy()
+        expect(Roles.userIsInRole).toHaveBeenCalledWith userId, ["admin"]
+
+    it "returns true if the user does have admin role", ->
+        userId = 1234
+        spyOn Roles, "userIsInRole"
+            .and.returnValue true
+        expect(authorizedUser(userId)).toBeTruthy()
+        expect(Roles.userIsInRole).toHaveBeenCalledWith userId, ["admin"]


only do conseq blocks of sup, no readability benefit otherwise

error: pathspec 'resource/Better' did not match any file(s) known to git
error: pathspec 'BibTeX.coffee' did not match any file(s) known to git


SidebarMachineBox: Added addWorkspace method and refactored to use it.


NavigationMachineItem: Temp fix to remove settings icon for participants.

--- client/Main/navigation/navigationmachineitem.coffee
+++ client/Main/navigation/navigationmachineitem.coffee
@@ -108,10 +108,15 @@

   pistachio:->
-
-    return """
+    cogMarkup = ''
+    template  = """

       {{> @label}}
-
+      #{cogMarkup}
       {{> @progress}}
     """
+
+    unless @getData().isMine()
+      template = template.replace cogMarkup, ''
+
+    return template


ide: syntax fix

ide: syntax fix


Moderation: Tag modifier is added for sending moderation events to exchanges


log group create fails

log group create fails

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/prognostikos/uploadcare-widget.git/'


Activity: hide location from activity items [Fixes #76463218]

--- client/Social/Activity/views/activitylistitem.coffee
+++ client/Social/Activity/views/activitylistitem.coffee
@@ -224,7 +224,7 @@
       {{> @avatar}}

         {{> @author}}
-        {{> @timeAgoView}}  from San Francisco
+        {{> @timeAgoView}}  from San Francisco

       {{> @editWidgetWrapper}}
       {article{@formatContent #(body)}}


activity: add fetchChannelMessages util

activity: add fetchChannelMessages util


Added a script that lets couchbot check for a CLA signature

error: pathspec 'couchbot/scripts/couchbasecla.coffee' did not match any file(s) known to git

--- couchbot/scripts/couchbasecla.coffee
+++ couchbot/scripts/couchbasecla.coffee
@@ -0,0 +1,90 @@
+# Description:
+#   Uses a Couchbase-specific script to check if CLA is signed.
+#
+# Dependencies:
+#   None
+#
+# Configuration:
+#   CLA_CHECK_URL: the base URL to the check script
+#   CLA_DEFAULT_OWNER: the default github organization to check if not provided (eg. 'couchbase')
+#
+# Commands:
+#   couchbot check cla for <email>
+#   couchbot check cla for <PR_NUMBER> in <REPO>
+#   couchbot check cla for <PR_NUMBER> in <ORGA>/<REPO>
+#   couchbot check cla for <PR_FULL_URL>
+#
+# Author:
+#   Simon Baslé <simon@couchbase.com>
+
+PATTERN_EMAIL = /(?:check )?cla for (.*@.*)/i
+PATTERN_PR_URL = /(?:check )?cla for https:\/\/github\.com\/([\w-]+)\/([\w-]+)\/pull\/(\d+)/i
+PATTERN_PR_REPO = /(?:check )?cla for (\d+) in ([\w-]+)$/i
+PATTERN_PR_OWNER_AND_REPO = /(?:check )?cla for (\d+) in ([\w-]+)\/([\w-]+)/i
+
+evaluateCla = (msg, url, res, typo=false) ->
+    res.http(url)
+      .get() (err, response, body) ->
+          try
+            if /not signed/i.test(body) and typo
+                res.reply "CLA doesn't appear to be signed for #{msg} :( maybe check the repo name / PR number?"
+            else if /not signed/i.test(body) and not typo
+                res.reply "CLA isn't signed for #{msg} :("
+            else if /signed/i.test(body)
+                res.reply "CLA is signed for #{msg} :)"
+            else
+                res.reply "I'm not sure about the CLA, I'm told that '#{body}'"
+          catch error
+            res.send "Sorry, couldn't check the CLA (error: #{error})"
+
+
+module.exports = (robot) ->
+    robot.respond PATTERN_EMAIL, (res) ->
+        res.message.done = true
+        claUser = escape(res.match[1])
+        claCheckUrl = process.env.CLA_CHECK_URL
+        if !!claCheckUrl
+            claMsg = "user #{claUser}"
+            claUrl = "#{claCheckUrl}/checkcla?email=#{claUser}"
+            evaluateCla(claMsg, claUrl, res)
+        else
+            res.send "Sorry, someone needs to define CLA_CHECK_URL"
+    robot.respond PATTERN_PR_REPO, (res) ->
+        res.message.done = true
+        claCheckUrl = process.env.CLA_CHECK_URL
+        claDefaultOwner = process.env.CLA_DEFAULT_OWNER
+        if claCheckUrl? and claDefaultOwner?
+            claPR = escape(res.match[1])
+            claRepo = res.match[2]
+            claMsg = "http://github.com/#{claDefaultOwner}/#{claRepo}/pull/#{claPR}"
+            claUrl = "#{claCheckUrl}/checkcla?owner=#{claDefaultOwner}&repo=#{claRepo}&prnum=#{claPR}"
+            evaluateCla(claMsg, claUrl, res, true)
+        else
+            res.send "Sorry, someone needs to define CLA_CHECK_URL and CLA_DEFAULT_OWNER"
+    robot.respond PATTERN_PR_OWNER_AND_REPO, (res) ->
+        #PR with both OWNER and REPO
+        res.message.done = true
+        claCheckUrl = process.env.CLA_CHECK_URL
+        if claCheckUrl?
+            claPR = escape(res.match[1])
+            claOwner = escape(res.match[2])
+            claRepo = escape(res.match[3])
+            claMsg = "http://github.com/#{claOwner}/#{claRepo}/pull/#{claPR}"
+            claUrl = "#{claCheckUrl}/checkcla?owner=#{claOwner}&repo=#{claRepo}&prnum=#{claPR}"
+            evaluateCla(claMsg, claUrl, res, true)
+        else
+            res.send "Sorry, someone needs to define CLA_CHECK_URL"
+    robot.respond PATTERN_PR_URL, (res) ->
+        res.message.done = true
+        claCheckUrl = process.env.CLA_CHECK_URL
+        if claCheckUrl?
+            claOwner = escape(res.match[1])
+            claRepo = escape(res.match[2])
+            claPR = escape(res.match[3])
+            claMsg = "http://github.com/#{claOwner}/#{claRepo}/pull/#{claPR}"
+            claUrl = "#{claCheckUrl}/checkcla?owner=#{claOwner}&repo=#{claRepo}&prnum=#{claPR}"
+            evaluateCla(claMsg, claUrl, res)
+        else
+            res.send "Sorry, someone needs to define CLA_CHECK_URL"
+    robot.respond /((?:check )?cla$|(?:check )?cla .*)/i, (res) ->
+        res.send "Sorry, I don't understand '#{res.match[1]}', cla command are either: 'check cla for EMAIL' or 'check cla for PR_NUMBER in [OWNER/]REPO'"