{"action":"created","comment":{"url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments/55429524","id":55429524,"diff_hunk":"@@ -0,0 +1,478 @@\n+/**\n+ * UI and function to quick search projects\n+ */\n+\n+var m = require('mithril');\n+var $osf = require('js/osfHelpers');\n+var Raven = require('raven-js');\n+\n+// CSS\n+require('css/quick-project-search-plugin.css');\n+\n+// XHR config for apiserver connection\n+var xhrconfig = function(xhr) {\n+    xhr.withCredentials = true;\n+};\n+\n+\n+var QuickSearchProject = {\n+    controller: function() {\n+        var self = this;\n+        self.nodes = m.prop([]); // Master node list\n+        self.eligibleNodes = m.prop([]); // Array of indices corresponding to self.nodes() that are eligible to be loaded\n+        self.sortState = m.prop('dateDesc'); //How nodes are sorted - default is date descending - dateDesc\n+        self.countDisplayed = m.prop(); // Max number of nodes that can be rendered.  'Load more' increases this by up to ten.\n+        self.next = m.prop(); // URL for getting the next ten user nodes. When null, all nodes are loaded.\n+        self.loadingComplete = m.prop(false); // True when all user nodes are loaded.\n+        self.contributorMapping = {}; // Maps node id to list of contributors for searching\n+        self.filter = m.prop(); // Search query from user\n+        self.fieldSort = m.prop(); // For xs screen, either alpha or date\n+        self.directionSort = m.prop(); // For xs screen, either Asc or Desc\n+        self.errorLoading = m.prop(false);\n+\n+        // Switches errorLoading to true\n+        self.requestError = function(result) {\n+            self.errorLoading(true);\n+            Raven.captureMessage('Error loading user projects on home page.', {requestReturn: result});\n+        };\n+\n+        // Load up to first ten nodes\n+        var url = $osf.apiV2Url('users/me/nodes/', { query : { 'embed': 'contributors'}});\n+        var promise = m.request({method: 'GET', url : url, config : xhrconfig});\n+        promise.then(function(result) {\n+            self.countDisplayed(result.data.length);\n+            result.data.forEach(function (node) {\n+                self.nodes().push(node);\n+                self.retrieveContributors(node);\n+            });\n+            self.populateEligibleNodes(0, self.countDisplayed());\n+            self.next(result.links.next);\n+        }, function _error(result){\n+            self.requestError(result);\n+        });\n+        promise.then(\n+            function(){\n+                if (self.next()) {\n+                    self.recursiveNodes(self.next());\n+                }\n+                else {\n+                    self.loadingComplete(true);\n+                }\n+            }, function _error(result){\n+                self.requestError(result);\n+            });\n+\n+        // Recursively fetches remaining user's nodes\n+        self.recursiveNodes = function (url) {\n+            if (self.next()) {\n+                var nextPromise = m.request({method: 'GET', url : url, config : xhrconfig, background : true});\n+                nextPromise.then(function(result){\n+                    result.data.forEach(function(node){\n+                        self.nodes().push(node);\n+                        self.retrieveContributors(node);\n+                    });\n+                self.populateEligibleNodes(self.eligibleNodes().length, self.nodes().length);\n+                self.next(result.links.next);\n+                self.recursiveNodes(self.next());\n+                }, function _error(result){\n+                    self.requestError(result);\n+                });\n+            }\n+            else {\n+                self.loadingComplete(true);\n+                m.redraw();\n+            }\n+        };\n+\n+        // Adds eligible node indices to array - used when no filter\n+        self.populateEligibleNodes = function (first, last) {\n+            for (var n = first; n < last; n++) {\n+                self.eligibleNodes().push(n);\n+            }\n+        };\n+\n+        // Returns true if there are nodes in the background that are not rendered on screen\n+        self.pendingNodes = function () {\n+            return (self.countDisplayed() < self.eligibleNodes().length);\n+        };\n+\n+\n+        // When 'load more' button pressed, loads up to 10 nodes\n+        self.loadUpToTen = function () {\n+            if (self.eligibleNodes().length - self.countDisplayed() >= 10) {\n+                self.countDisplayed(self.countDisplayed() + 10);\n+            }\n+            else {\n+                self.countDisplayed(self.eligibleNodes().length);\n+            }\n+        };\n+\n+        // If < 10 contribs, map node id to contrib names. Otherwise, make a call to get all contribs.\n+        self.retrieveContributors = function(node) {\n+            if (node.embeds.contributors.links.meta.total > 10) {\n+                self.pullOverTenContributorNames(node);\n+            }\n+            else {\n+                var contributors = node.embeds.contributors;\n+                self.mapNodeToContributors(node, contributors);\n+            }\n+        };\n+\n+        // Call to get up to 1000 contributors on a node.\n+        self.pullOverTenContributorNames = function (node) {\n+            var url = $osf.apiV2Url('nodes/' + node.id + '/contributors/', { query : { 'page[size]': 1000 }});\n+            var promise = m.request({method: 'GET', url : url, config: xhrconfig, background : true});\n+            promise.then(function(result){\n+                self.mapNodeToContributors(node, result);\n+            });\n+        };\n+\n+        // Maps node id to list of contrib names for later searching\n+        self.mapNodeToContributors = function (node, contributors){\n+            var contributorList = [];\n+            contributors.data.forEach(function(contrib){\n+                fullName = contrib.embeds.users.data.attributes.full_name;\n+                contributorList.push(fullName);\n+            });\n+            self.contributorMapping[node.id] = contributorList;\n+        };\n+\n+        // Gets contrib family name for display\n+        self.getFamilyName = function(i, node) {\n+            var attributes = node.embeds.contributors.data[i].embeds.users.data.attributes;\n+            return $osf.findContribName(attributes);\n+        };\n+\n+         // Formats date for display\n+        self.formatDate = function (node) {\n+            return new $osf.FormattableDate(node.attributes.date_modified).local;\n+        };\n+\n+        // Shortcut for sorting ascending\n+        self.sortAscending = function (A, B) {\n+            return (A < B) ? -1 : (A > B) ? 1 : 0;\n+        };\n+\n+        // Shortcut for sorting descending\n+        self.sortDescending = function (A, B) {\n+            return (A > B) ? -1 : (A < B) ? 1 : 0;\n+        };\n+\n+        self.sortAlphabeticalAscending = function () {\n+            self.nodes().sort(function(a,b){\n+                var A = a.attributes.title.toUpperCase();\n+                var B = b.attributes.title.toUpperCase();\n+                return self.sortAscending(A, B);\n+            });\n+            self.sortState('alphaAsc');\n+        };\n+\n+        self.sortAlphabeticalDescending = function () {\n+            self.nodes().sort(function(a,b){\n+                var A = a.attributes.title.toUpperCase();\n+                var B = b.attributes.title.toUpperCase();\n+                return self.sortDescending(A, B);\n+            });\n+            self.sortState('alphaDesc');\n+        };\n+\n+        self.sortDateAscending = function () {\n+            self.nodes().sort(function(a,b){\n+                var A = a.attributes.date_modified;\n+                var B = b.attributes.date_modified;\n+                return self.sortAscending(A, B);\n+            });\n+            self.sortState('dateAsc');\n+        };\n+\n+        self.sortDateDescending = function () {\n+            self.nodes().sort(function(a,b){\n+                var A = a.attributes.date_modified;\n+                var B = b.attributes.date_modified;\n+                return self.sortDescending(A, B);\n+            });\n+            self.sortState('dateDesc');\n+        };\n+\n+        // Sorts nodes depending on current sort state.\n+        self.sortBySortState = function () {\n+            switch (self.sortState()) {\n+                case 'alphaAsc':\n+                    self.sortAlphabeticalAscending();\n+                    break;\n+                case 'alphaDesc':\n+                    self.sortAlphabeticalDescending();\n+                    break;\n+                case 'dateAsc':\n+                    self.sortDateAscending();\n+                    break;\n+                default:\n+                    self.sortDateDescending();\n+            }\n+            if (self.filter()) {\n+                self.quickSearch();\n+            }\n+        };\n+\n+        // For xs screen\n+        self.sortFieldGivenDirection = function(){\n+            var directionSort = self.preSelectDirection();\n+            self.sortState(self.fieldSort() + directionSort);\n+            self.sortBySortState();\n+        };\n+\n+        // For xs screen\n+        self.sortDirectionGivenField = function() {\n+            var fieldSort = self.preSelectField();\n+            self.sortState(fieldSort + self.directionSort());\n+            self.sortBySortState();\n+        };\n+\n+        // When shifting to xs screen, tells which field to automatically display in select\n+        self.preSelectField = function(){\n+            return self.sortState().split(/[A-Z][a-z]+/g)[0];\n+        };\n+\n+        // When shifting to xs screen, tells which direction to automatically highlight in select\n+        self.preSelectDirection = function(){\n+            return self.sortState().match(/[A-Z][a-z]+/g)[0];\n+        };\n+\n+        // Colors sort asc/desc buttons either selected or not-selected\n+        self.colorSortButtons = function (sort) {\n+            return self.sortState() === sort ? 'selected' : 'not-selected';\n+        };\n+\n+        // Colors asc/desc buttons on XS screen\n+        self.colorSortButtonsXS = function (sort) {\n+            return self.preSelectDirection() === sort ? 'selected' : 'not-selected';\n+        };\n+\n+        // Filtering on title\n+        self.titleMatch = function (node) {\n+            return (node.attributes.title.toUpperCase().indexOf(self.filter().toUpperCase()) !== -1);\n+        };\n+\n+        // Filtering on contrib\n+        self.contributorMatch = function (node) {\n+            var contributors = self.contributorMapping[node.id];\n+            for (var c = 0; c < contributors.length; c++) {\n+                if (contributors[c].toUpperCase().indexOf(self.filter().toUpperCase()) !== -1){\n+                    return true;\n+                }\n+            }\n+            return false;\n+        };\n+\n+        // Filtering on tag\n+        self.tagMatch = function (node) {\n+            var tags = node.attributes.tags;\n+            for (var t = 0; t < tags.length; t++){\n+                if (tags[t].toUpperCase().indexOf(self.filter().toUpperCase()) !== -1) {\n+                    return true;\n+                }\n+            }\n+            return false;\n+        };\n+\n+        // Filters nodes\n+        self.filterNodes = function (){\n+            for (var n = 0;  n < self.nodes().length;  n++) {\n+                var node = self.nodes()[n];\n+                if (self.titleMatch(node) || self.contributorMatch(node) || self.tagMatch(node)) {\n+                    self.eligibleNodes().push(n);\n+                }\n+            }\n+        };\n+\n+        self.quickSearch = function () {\n+            self.eligibleNodes([]);\n+            // if backspace completely, previous nodes with prior sorting/count will be displayed\n+            if (self.filter() === '') {\n+                self.populateEligibleNodes(0, self.nodes().length);\n+            }\n+            else {\n+                self.filterNodes();\n+            }\n+        };\n+\n+        // Onclick, directs user to project page\n+        self.nodeDirect = function(node) {\n+            location.href = '/'+ node.id;\n+        };\n+\n+    },\n+    view : function(ctrl) {\n+        if (ctrl.errorLoading()) {\n+            return m('p.text-center.m-v-md', 'Error loading projects. Please refresh the page.');\n+        }\n+\n+        function loadMoreButton(){\n+            if (ctrl.pendingNodes()){\n+                return m('button.col-sm-12.text-muted', {onclick: function(){\n+                    ctrl.loadUpToTen();\n+                }},\n+                    m('i.fa.fa-caret-down.load-nodes.m-b-xl'));\n+            }\n+        }\n+\n+        function sortAlphaAsc() {\n+            if (ctrl.loadingComplete()) {\n+                return m('button', {'class': ctrl.colorSortButtons('alphaAsc'), onclick: function() {\n+                    ctrl.sortBySortState(ctrl.sortState('alphaAsc'));\n+                }},\n+                    m('i.fa.fa-angle-up'));\n+            }\n+        }\n+\n+        function sortAlphaDesc(){\n+            if (ctrl.loadingComplete()){\n+                return m('button', {'class': ctrl.colorSortButtons('alphaDesc'), onclick: function() {\n+                    ctrl.sortBySortState(ctrl.sortState('alphaDesc'));\n+                }},\n+                    m('i.fa.fa-angle-down'));\n+            }\n+        }\n+\n+        function sortDateAsc(){\n+            if (ctrl.loadingComplete()){\n+                 return m('button', {'class': ctrl.colorSortButtons('dateAsc'), onclick: function() {\n+                     ctrl.sortBySortState(ctrl.sortState('dateAsc'));\n+                 }},\n+                     m('i.fa.fa-angle-up'));\n+            }\n+        }\n+\n+        function sortDateDesc(){\n+            if (ctrl.loadingComplete()){\n+                return m('button', {'class': ctrl.colorSortButtons('dateDesc'), onclick: function() {\n+                    ctrl.sortBySortState(ctrl.sortState('dateDesc'));\n+               }},\n+                    m('i.fa.fa-angle-down'));\n+            }\n+        }\n+\n+        // Sort button for xs screen\n+        function ascending() {\n+            if (ctrl.loadingComplete()){\n+                return m('button', {'class': ctrl.colorSortButtonsXS('Asc'), onclick: function() {\n+                     ctrl.directionSort('Asc');\n+                     ctrl.sortDirectionGivenField();\n+                }},\n+                     m('i.fa.fa-angle-up'));\n+            }\n+        }\n+\n+        // Sort button for xs screen\n+        function descending() {\n+            if (ctrl.loadingComplete()){\n+                return m('button', {'class': ctrl.colorSortButtonsXS('Desc'), onclick: function() {\n+                    ctrl.directionSort('Desc');\n+                    ctrl.sortDirectionGivenField();\n+                }},\n+                     m('i.fa.fa-angle-down'));\n+            }\n+        }\n+\n+        // Dropdown for XS screen - if sort on title on large screen, when resize to xs, 'title' is default selected\n+        function defaultSelected() {\n+            var selected = ctrl.preSelectField();\n+            if (selected === 'alpha') {\n+                return [m('option', {value: 'alpha', selected:'selected'}, 'Title'), m('option', {value: 'date'}, 'Modified')];\n+            }\n+            else {\n+                return [m('option', {value: 'alpha'}, 'Title'), m('option', {value: 'date', selected:'selected'}, 'Modified')];\n+            }\n+        }\n+\n+        function searchBar() {\n+            if (ctrl.loadingComplete()){\n+                return m('div.m-v-sm.quick-search-input', [\n+                    m('input[type=search]', {'id': 'searchQuery', 'class': 'form-control', placeholder: 'Quick search projects', onkeyup: function(search) {\n+                        ctrl.filter(search.target.value);\n+                        ctrl.quickSearch();\n+                    }}),\n+                    m('span', {onclick: function() {\n+                        ctrl.filter('');\n+                        document.getElementById('searchQuery').value = '';\n+                        ctrl.quickSearch();\n+                    }},  m('button', m('i.fa.fa-times')))\n+                ]);\n+            }\n+        }\n+\n+        function displayNodes() {","path":"website/static/js/quickProjectSearchPlugin.js","position":null,"original_position":404,"commit_id":"a4f95797f893cd47893a189a956eb712c9c32009","original_commit_id":"7b19a270a8f415615529fe0bbb40ebfcf48ea441","user":{"login":"sloria","id":2379650,"avatar_url":"https://avatars.githubusercontent.com/u/2379650?v=3","gravatar_id":"","url":"https://api.github.com/users/sloria","html_url":"https://github.com/sloria","followers_url":"https://api.github.com/users/sloria/followers","following_url":"https://api.github.com/users/sloria/following{/other_user}","gists_url":"https://api.github.com/users/sloria/gists{/gist_id}","starred_url":"https://api.github.com/users/sloria/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sloria/subscriptions","organizations_url":"https://api.github.com/users/sloria/orgs","repos_url":"https://api.github.com/users/sloria/repos","events_url":"https://api.github.com/users/sloria/events{/privacy}","received_events_url":"https://api.github.com/users/sloria/received_events","type":"User","site_admin":false},"body":"For another example, see how I wrote `onClickNode` above.","created_at":"2016-03-08T21:20:55Z","updated_at":"2016-03-08T21:20:55Z","html_url":"https://github.com/CenterForOpenScience/osf.io/pull/5119#discussion_r55429524","pull_request_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5119","_links":{"self":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments/55429524"},"html":{"href":"https://github.com/CenterForOpenScience/osf.io/pull/5119#discussion_r55429524"},"pull_request":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5119"}}},"pull_request":{"url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5119","id":61626003,"html_url":"https://github.com/CenterForOpenScience/osf.io/pull/5119","diff_url":"https://github.com/CenterForOpenScience/osf.io/pull/5119.diff","patch_url":"https://github.com/CenterForOpenScience/osf.io/pull/5119.patch","issue_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/5119","number":5119,"state":"open","locked":false,"title":"Dashboard Redesign with Home page elements","user":{"login":"caneruguz","id":1314003,"avatar_url":"https://avatars.githubusercontent.com/u/1314003?v=3","gravatar_id":"","url":"https://api.github.com/users/caneruguz","html_url":"https://github.com/caneruguz","followers_url":"https://api.github.com/users/caneruguz/followers","following_url":"https://api.github.com/users/caneruguz/following{/other_user}","gists_url":"https://api.github.com/users/caneruguz/gists{/gist_id}","starred_url":"https://api.github.com/users/caneruguz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caneruguz/subscriptions","organizations_url":"https://api.github.com/users/caneruguz/orgs","repos_url":"https://api.github.com/users/caneruguz/repos","events_url":"https://api.github.com/users/caneruguz/events{/privacy}","received_events_url":"https://api.github.com/users/caneruguz/received_events","type":"User","site_admin":false},"body":"## Purpose\r\nA combined home page, support page and navigation changes to finish off the Stage 1. \r\n\r\n## Changes\r\nHome page is now a layered content based on the wireframes. It includes several sections\r\n- Quick Search\r\n- Recent activity widgets\r\n- New and Noteworthy Items\r\n- Meetings banner\r\n\r\nThere is a new support page, but getting started is still it's own page with some edits\r\n\r\nNavigation has changed based on wireframe\r\n\r\nmore details coming... \r\nTag @pattisdr for Quick search and new and noteworthy, tag @hmoco for Recent activity widgets, tag me for anything else. ","created_at":"2016-03-03T21:13:17Z","updated_at":"2016-03-08T21:20:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2c128fec0ea85ec57e5952934b27b7943cd59517","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5119/commits","review_comments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5119/comments","review_comment_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments{/number}","comments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/5119/comments","statuses_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/statuses/a4f95797f893cd47893a189a956eb712c9c32009","head":{"label":"caneruguz:dashboard-redesign-2","ref":"dashboard-redesign-2","sha":"a4f95797f893cd47893a189a956eb712c9c32009","user":{"login":"caneruguz","id":1314003,"avatar_url":"https://avatars.githubusercontent.com/u/1314003?v=3","gravatar_id":"","url":"https://api.github.com/users/caneruguz","html_url":"https://github.com/caneruguz","followers_url":"https://api.github.com/users/caneruguz/followers","following_url":"https://api.github.com/users/caneruguz/following{/other_user}","gists_url":"https://api.github.com/users/caneruguz/gists{/gist_id}","starred_url":"https://api.github.com/users/caneruguz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caneruguz/subscriptions","organizations_url":"https://api.github.com/users/caneruguz/orgs","repos_url":"https://api.github.com/users/caneruguz/repos","events_url":"https://api.github.com/users/caneruguz/events{/privacy}","received_events_url":"https://api.github.com/users/caneruguz/received_events","type":"User","site_admin":false},"repo":{"id":27096151,"name":"osf.io","full_name":"caneruguz/osf.io","owner":{"login":"caneruguz","id":1314003,"avatar_url":"https://avatars.githubusercontent.com/u/1314003?v=3","gravatar_id":"","url":"https://api.github.com/users/caneruguz","html_url":"https://github.com/caneruguz","followers_url":"https://api.github.com/users/caneruguz/followers","following_url":"https://api.github.com/users/caneruguz/following{/other_user}","gists_url":"https://api.github.com/users/caneruguz/gists{/gist_id}","starred_url":"https://api.github.com/users/caneruguz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caneruguz/subscriptions","organizations_url":"https://api.github.com/users/caneruguz/orgs","repos_url":"https://api.github.com/users/caneruguz/repos","events_url":"https://api.github.com/users/caneruguz/events{/privacy}","received_events_url":"https://api.github.com/users/caneruguz/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/caneruguz/osf.io","description":"Facilitating Open Science","fork":true,"url":"https://api.github.com/repos/caneruguz/osf.io","forks_url":"https://api.github.com/repos/caneruguz/osf.io/forks","keys_url":"https://api.github.com/repos/caneruguz/osf.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/caneruguz/osf.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/caneruguz/osf.io/teams","hooks_url":"https://api.github.com/repos/caneruguz/osf.io/hooks","issue_events_url":"https://api.github.com/repos/caneruguz/osf.io/issues/events{/number}","events_url":"https://api.github.com/repos/caneruguz/osf.io/events","assignees_url":"https://api.github.com/repos/caneruguz/osf.io/assignees{/user}","branches_url":"https://api.github.com/repos/caneruguz/osf.io/branches{/branch}","tags_url":"https://api.github.com/repos/caneruguz/osf.io/tags","blobs_url":"https://api.github.com/repos/caneruguz/osf.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/caneruguz/osf.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/caneruguz/osf.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/caneruguz/osf.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/caneruguz/osf.io/statuses/{sha}","languages_url":"https://api.github.com/repos/caneruguz/osf.io/languages","stargazers_url":"https://api.github.com/repos/caneruguz/osf.io/stargazers","contributors_url":"https://api.github.com/repos/caneruguz/osf.io/contributors","subscribers_url":"https://api.github.com/repos/caneruguz/osf.io/subscribers","subscription_url":"https://api.github.com/repos/caneruguz/osf.io/subscription","commits_url":"https://api.github.com/repos/caneruguz/osf.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/caneruguz/osf.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/caneruguz/osf.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/caneruguz/osf.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/caneruguz/osf.io/contents/{+path}","compare_url":"https://api.github.com/repos/caneruguz/osf.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/caneruguz/osf.io/merges","archive_url":"https://api.github.com/repos/caneruguz/osf.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/caneruguz/osf.io/downloads","issues_url":"https://api.github.com/repos/caneruguz/osf.io/issues{/number}","pulls_url":"https://api.github.com/repos/caneruguz/osf.io/pulls{/number}","milestones_url":"https://api.github.com/repos/caneruguz/osf.io/milestones{/number}","notifications_url":"https://api.github.com/repos/caneruguz/osf.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/caneruguz/osf.io/labels{/name}","releases_url":"https://api.github.com/repos/caneruguz/osf.io/releases{/id}","deployments_url":"https://api.github.com/repos/caneruguz/osf.io/deployments","created_at":"2014-11-24T21:33:09Z","updated_at":"2015-06-14T17:00:49Z","pushed_at":"2016-03-08T21:16:22Z","git_url":"git://github.com/caneruguz/osf.io.git","ssh_url":"git@github.com:caneruguz/osf.io.git","clone_url":"https://github.com/caneruguz/osf.io.git","svn_url":"https://github.com/caneruguz/osf.io","homepage":"http://osf.io","size":122768,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":3,"forks":0,"open_issues":3,"watchers":0,"default_branch":"develop"}},"base":{"label":"CenterForOpenScience:feature/dashboard","ref":"feature/dashboard","sha":"88a5ba6a7be1f79044c785ebfbfae0c6d84ab60c","user":{"login":"CenterForOpenScience","id":3344584,"avatar_url":"https://avatars.githubusercontent.com/u/3344584?v=3","gravatar_id":"","url":"https://api.github.com/users/CenterForOpenScience","html_url":"https://github.com/CenterForOpenScience","followers_url":"https://api.github.com/users/CenterForOpenScience/followers","following_url":"https://api.github.com/users/CenterForOpenScience/following{/other_user}","gists_url":"https://api.github.com/users/CenterForOpenScience/gists{/gist_id}","starred_url":"https://api.github.com/users/CenterForOpenScience/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CenterForOpenScience/subscriptions","organizations_url":"https://api.github.com/users/CenterForOpenScience/orgs","repos_url":"https://api.github.com/users/CenterForOpenScience/repos","events_url":"https://api.github.com/users/CenterForOpenScience/events{/privacy}","received_events_url":"https://api.github.com/users/CenterForOpenScience/received_events","type":"Organization","site_admin":false},"repo":{"id":10199599,"name":"osf.io","full_name":"CenterForOpenScience/osf.io","owner":{"login":"CenterForOpenScience","id":3344584,"avatar_url":"https://avatars.githubusercontent.com/u/3344584?v=3","gravatar_id":"","url":"https://api.github.com/users/CenterForOpenScience","html_url":"https://github.com/CenterForOpenScience","followers_url":"https://api.github.com/users/CenterForOpenScience/followers","following_url":"https://api.github.com/users/CenterForOpenScience/following{/other_user}","gists_url":"https://api.github.com/users/CenterForOpenScience/gists{/gist_id}","starred_url":"https://api.github.com/users/CenterForOpenScience/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CenterForOpenScience/subscriptions","organizations_url":"https://api.github.com/users/CenterForOpenScience/orgs","repos_url":"https://api.github.com/users/CenterForOpenScience/repos","events_url":"https://api.github.com/users/CenterForOpenScience/events{/privacy}","received_events_url":"https://api.github.com/users/CenterForOpenScience/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CenterForOpenScience/osf.io","description":"Facilitating Open Science","fork":false,"url":"https://api.github.com/repos/CenterForOpenScience/osf.io","forks_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/forks","keys_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/teams","hooks_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/hooks","issue_events_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/events{/number}","events_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/events","assignees_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/assignees{/user}","branches_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/branches{/branch}","tags_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/tags","blobs_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/statuses/{sha}","languages_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/languages","stargazers_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/stargazers","contributors_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/contributors","subscribers_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/subscribers","subscription_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/subscription","commits_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/contents/{+path}","compare_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/merges","archive_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/downloads","issues_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues{/number}","pulls_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls{/number}","milestones_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/milestones{/number}","notifications_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/labels{/name}","releases_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/releases{/id}","deployments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/deployments","created_at":"2013-05-21T15:53:37Z","updated_at":"2016-03-03T06:04:49Z","pushed_at":"2016-03-08T21:16:22Z","git_url":"git://github.com/CenterForOpenScience/osf.io.git","ssh_url":"git@github.com:CenterForOpenScience/osf.io.git","clone_url":"https://github.com/CenterForOpenScience/osf.io.git","svn_url":"https://github.com/CenterForOpenScience/osf.io","homepage":"http://osf.io","size":267658,"stargazers_count":197,"watchers_count":197,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":156,"mirror_url":null,"open_issues_count":271,"forks":156,"open_issues":271,"watchers":197,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5119"},"html":{"href":"https://github.com/CenterForOpenScience/osf.io/pull/5119"},"issue":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/5119"},"comments":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/5119/comments"},"review_comments":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5119/comments"},"review_comment":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/5119/commits"},"statuses":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/statuses/a4f95797f893cd47893a189a956eb712c9c32009"}}}}