diff options
96 files changed, 3716 insertions, 351 deletions
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index 627a3f43a64..0062ac97180 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -4.1.1 +5.0.0 diff --git a/app/assets/javascripts/diff_notes/components/diff_note_avatars.js b/app/assets/javascripts/diff_notes/components/diff_note_avatars.js new file mode 100644 index 00000000000..788daa96b3d --- /dev/null +++ b/app/assets/javascripts/diff_notes/components/diff_note_avatars.js @@ -0,0 +1,155 @@ +/* global CommentsStore Cookies notes */ +import Vue from 'vue'; +import collapseIcon from '../icons/collapse_icon.svg'; + +(() => { + const DiffNoteAvatars = Vue.extend({ + props: ['discussionId'], + data() { + return { + isVisible: false, + lineType: '', + storeState: CommentsStore.state, + shownAvatars: 3, + collapseIcon, + }; + }, + template: ` + <div class="diff-comment-avatar-holders" + v-show="notesCount !== 0"> + <div v-if="!isVisible"> + <img v-for="note in notesSubset" + class="avatar diff-comment-avatar has-tooltip js-diff-comment-avatar" + width="19" + height="19" + role="button" + data-container="body" + data-placement="top" + :data-line-type="lineType" + :title="note.authorName + ': ' + note.noteTruncated" + :src="note.authorAvatar" + @click="clickedAvatar($event)" /> + <span v-if="notesCount > shownAvatars" + class="diff-comments-more-count has-tooltip js-diff-comment-avatar" + data-container="body" + data-placement="top" + ref="extraComments" + role="button" + :data-line-type="lineType" + :title="extraNotesTitle" + @click="clickedAvatar($event)">{{ moreText }}</span> + </div> + <button class="diff-notes-collapse js-diff-comment-avatar" + type="button" + aria-label="Show comments" + :data-line-type="lineType" + @click="clickedAvatar($event)" + v-if="isVisible" + v-html="collapseIcon"> + </button> + </div> + `, + mounted() { + this.$nextTick(() => { + this.addNoCommentClass(); + this.setDiscussionVisible(); + + this.lineType = $(this.$el).closest('.diff-line-num').hasClass('old_line') ? 'old' : 'new'; + }); + + $(document).on('toggle.comments', () => { + this.$nextTick(() => { + this.setDiscussionVisible(); + }); + }); + }, + destroyed() { + $(document).off('toggle.comments'); + }, + watch: { + storeState: { + handler() { + this.$nextTick(() => { + $('.has-tooltip', this.$el).tooltip('fixTitle'); + + // We need to add/remove a class to an element that is outside the Vue instance + this.addNoCommentClass(); + }); + }, + deep: true, + }, + }, + computed: { + notesSubset() { + let notes = []; + + if (this.discussion) { + notes = Object.keys(this.discussion.notes) + .slice(0, this.shownAvatars) + .map(noteId => this.discussion.notes[noteId]); + } + + return notes; + }, + extraNotesTitle() { + if (this.discussion) { + const extra = this.discussion.notesCount() - this.shownAvatars; + + return `${extra} more comment${extra > 1 ? 's' : ''}`; + } + + return ''; + }, + discussion() { + return this.storeState[this.discussionId]; + }, + notesCount() { + if (this.discussion) { + return this.discussion.notesCount(); + } + + return 0; + }, + moreText() { + const plusSign = this.notesCount < 100 ? '+' : ''; + + return `${plusSign}${this.notesCount - this.shownAvatars}`; + }, + }, + methods: { + clickedAvatar(e) { + notes.addDiffNote(e); + + // Toggle the active state of the toggle all button + this.toggleDiscussionsToggleState(); + + this.$nextTick(() => { + this.setDiscussionVisible(); + + $('.has-tooltip', this.$el).tooltip('fixTitle'); + $('.has-tooltip', this.$el).tooltip('hide'); + }); + }, + addNoCommentClass() { + const notesCount = this.notesCount; + + $(this.$el).closest('.js-avatar-container') + .toggleClass('js-no-comment-btn', notesCount > 0) + .nextUntil('.js-avatar-container') + .toggleClass('js-no-comment-btn', notesCount > 0); + }, + toggleDiscussionsToggleState() { + const $notesHolders = $(this.$el).closest('.code').find('.notes_holder'); + const $visibleNotesHolders = $notesHolders.filter(':visible'); + const $toggleDiffCommentsBtn = $(this.$el).closest('.diff-file').find('.js-toggle-diff-comments'); + + $toggleDiffCommentsBtn.toggleClass('active', $notesHolders.length === $visibleNotesHolders.length); + }, + setDiscussionVisible() { + this.isVisible = $(`.diffs .notes[data-discussion-id="${this.discussion.id}"]`).is(':visible'); + }, + }, + }); + + Vue.component('diff-note-avatars', DiffNoteAvatars); +})(); diff --git a/app/assets/javascripts/diff_notes/components/resolve_btn.js b/app/assets/javascripts/diff_notes/components/resolve_btn.js index d1873d6c7a2..fbd980f0fce 100644 --- a/app/assets/javascripts/diff_notes/components/resolve_btn.js +++ b/app/assets/javascripts/diff_notes/components/resolve_btn.js @@ -11,7 +11,10 @@ const Vue = require('vue'); discussionId: String, resolved: Boolean, canResolve: Boolean, - resolvedBy: String + resolvedBy: String, + authorName: String, + authorAvatar: String, + noteTruncated: String, }, data: function () { return { @@ -98,7 +101,16 @@ const Vue = require('vue'); CommentsStore.delete(this.discussionId, this.noteId); }, created: function () { - CommentsStore.create(this.discussionId, this.noteId, this.canResolve, this.resolved, this.resolvedBy); + CommentsStore.create({ + discussionId: this.discussionId, + noteId: this.noteId, + canResolve: this.canResolve, + resolved: this.resolved, + resolvedBy: this.resolvedBy, + authorName: this.authorName, + authorAvatar: this.authorAvatar, + noteTruncated: this.noteTruncated, + }); this.note = this.discussion.getNote(this.noteId); } diff --git a/app/assets/javascripts/diff_notes/diff_notes_bundle.js b/app/assets/javascripts/diff_notes/diff_notes_bundle.js index cadf8b96b87..7d8316dfd63 100644 --- a/app/assets/javascripts/diff_notes/diff_notes_bundle.js +++ b/app/assets/javascripts/diff_notes/diff_notes_bundle.js @@ -13,6 +13,7 @@ require('./components/jump_to_discussion'); require('./components/resolve_btn'); require('./components/resolve_count'); require('./components/resolve_discussion_btn'); +require('./components/diff_note_avatars'); $(() => { const projectPath = document.querySelector('.merge-request').dataset.projectPath; @@ -24,6 +25,15 @@ $(() => { window.ResolveService = new gl.DiffNotesResolveServiceClass(projectPath); gl.diffNotesCompileComponents = () => { + $('diff-note-avatars').each(function () { + const tmp = Vue.extend({ + template: $(this).get(0).outerHTML + }); + const tmpApp = new tmp().$mount(); + + $(this).replaceWith(tmpApp.$el); + }); + const $components = $(COMPONENT_SELECTOR).filter(function () { return $(this).closest('resolve-count').length !== 1; }); diff --git a/app/assets/javascripts/diff_notes/icons/collapse_icon.svg b/app/assets/javascripts/diff_notes/icons/collapse_icon.svg new file mode 100644 index 00000000000..bd4b393cfaa --- /dev/null +++ b/app/assets/javascripts/diff_notes/icons/collapse_icon.svg @@ -0,0 +1 @@ +<svg width="11" height="11" viewBox="0 0 9 13"><path d="M2.57568253,6.49866948 C2.50548852,6.57199715 2.44637866,6.59708255 2.39835118,6.57392645 C2.3503237,6.55077034 2.32631032,6.48902165 2.32631032,6.38867852 L2.32631032,-2.13272614 C2.32631032,-2.23306927 2.3503237,-2.29481796 2.39835118,-2.31797406 C2.44637866,-2.34113017 2.50548852,-2.31604477 2.57568253,-2.24271709 L6.51022184,1.86747129 C6.53977721,1.8983461 6.56379059,1.93500939 6.5822627,1.97746225 L6.5822627,2.27849013 C6.56379059,2.31708364 6.53977721,2.35374693 6.51022184,2.38848109 L2.57568253,6.49866948 Z" transform="translate(4.454287, 2.127976) rotate(90.000000) translate(-4.454287, -2.127976) "></path><path d="M3.74312342,2.09553332 C3.74312342,1.99519019 3.77821989,1.9083561 3.8484139,1.83502843 C3.91860791,1.76170075 4.00173115,1.72503747 4.09778611,1.72503747 L4.80711151,1.72503747 C4.90316647,1.72503747 4.98628971,1.76170075 5.05648372,1.83502843 C5.12667773,1.9083561 5.16177421,1.99519019 5.16177421,2.09553332 L5.16177421,10.2464421 C5.16177421,10.3467853 5.12667773,10.4336194 5.05648372,10.506947 C4.98628971,10.5802747 4.90316647,10.616938 4.80711151,10.616938 L4.09778611,10.616938 C4.00173115,10.616938 3.91860791,10.5802747 3.8484139,10.506947 C3.77821989,10.4336194 3.74312342,10.3467853 3.74312342,10.2464421 L3.74312342,2.09553332 Z" transform="translate(4.452449, 6.170988) rotate(-90.000000) translate(-4.452449, -6.170988) "></path><path d="M2.57568253,14.6236695 C2.50548852,14.6969971 2.44637866,14.7220826 2.39835118,14.6989264 C2.3503237,14.6757703 2.32631032,14.6140216 2.32631032,14.5136785 L2.32631032,5.99227386 C2.32631032,5.89193073 2.3503237,5.83018204 2.39835118,5.80702594 C2.44637866,5.78386983 2.50548852,5.80895523 2.57568253,5.88228291 L6.51022184,9.99247129 C6.53977721,10.0233461 6.56379059,10.0600094 6.5822627,10.1024622 L6.5822627,10.4034901 C6.56379059,10.4420836 6.53977721,10.4787469 6.51022184,10.5134811 L2.57568253,14.6236695 Z" transform="translate(4.454287, 10.252976) scale(1, -1) rotate(90.000000) translate(-4.454287, -10.252976) "></path></svg> diff --git a/app/assets/javascripts/diff_notes/models/discussion.js b/app/assets/javascripts/diff_notes/models/discussion.js index fa518ba4d33..dce1a9b58bd 100644 --- a/app/assets/javascripts/diff_notes/models/discussion.js +++ b/app/assets/javascripts/diff_notes/models/discussion.js @@ -10,8 +10,8 @@ class DiscussionModel { this.canResolve = false; } - createNote (noteId, canResolve, resolved, resolved_by) { - Vue.set(this.notes, noteId, new NoteModel(this.id, noteId, canResolve, resolved, resolved_by)); + createNote (noteObj) { + Vue.set(this.notes, noteObj.noteId, new NoteModel(this.id, noteObj)); } deleteNote (noteId) { diff --git a/app/assets/javascripts/diff_notes/models/note.js b/app/assets/javascripts/diff_notes/models/note.js index f3a7cba5ef6..04465aa507e 100644 --- a/app/assets/javascripts/diff_notes/models/note.js +++ b/app/assets/javascripts/diff_notes/models/note.js @@ -1,12 +1,15 @@ /* eslint-disable camelcase, no-unused-vars */ class NoteModel { - constructor(discussionId, noteId, canResolve, resolved, resolved_by) { + constructor(discussionId, noteObj) { this.discussionId = discussionId; - this.id = noteId; - this.canResolve = canResolve; - this.resolved = resolved; - this.resolved_by = resolved_by; + this.id = noteObj.noteId; + this.canResolve = noteObj.canResolve; + this.resolved = noteObj.resolved; + this.resolved_by = noteObj.resolvedBy; + this.authorName = noteObj.authorName; + this.authorAvatar = noteObj.authorAvatar; + this.noteTruncated = noteObj.noteTruncated; } } diff --git a/app/assets/javascripts/diff_notes/stores/comments.js b/app/assets/javascripts/diff_notes/stores/comments.js index c80d979b977..69c4d7a8434 100644 --- a/app/assets/javascripts/diff_notes/stores/comments.js +++ b/app/assets/javascripts/diff_notes/stores/comments.js @@ -21,10 +21,10 @@ return discussion; }, - create: function (discussionId, noteId, canResolve, resolved, resolved_by) { - const discussion = this.createDiscussion(discussionId); + create: function (noteObj) { + const discussion = this.createDiscussion(noteObj.discussionId); - discussion.createNote(noteId, canResolve, resolved, resolved_by); + discussion.createNote(noteObj); }, update: function (discussionId, noteId, resolved, resolved_by) { const discussion = this.state[discussionId]; diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 546bdc9c8d7..017980271b1 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -5,7 +5,6 @@ import PrometheusGraph from './monitoring/prometheus_graph'; // TODO: Maybe Make /* global ShortcutsNavigation */ /* global Build */ /* global Issuable */ -/* global Issue */ /* global ShortcutsIssuable */ /* global ZenMode */ /* global Milestone */ @@ -35,6 +34,7 @@ import PrometheusGraph from './monitoring/prometheus_graph'; // TODO: Maybe Make /* global ProjectShow */ /* global Labels */ /* global Shortcuts */ +import Issue from './issue'; import BindInOut from './behaviors/bind_in_out'; import GroupsList from './groups_list'; diff --git a/app/assets/javascripts/files_comment_button.js b/app/assets/javascripts/files_comment_button.js index 6d86888dcb8..bf84f2a0a8f 100644 --- a/app/assets/javascripts/files_comment_button.js +++ b/app/assets/javascripts/files_comment_button.js @@ -38,6 +38,9 @@ FilesCommentButton.prototype.render = function(e) { var $currentTarget, buttonParentElement, lineContentElement, textFileElement, $button; $currentTarget = $(e.currentTarget); + + if ($currentTarget.hasClass('js-no-comment-btn')) return; + lineContentElement = this.getLineContent($currentTarget); buttonParentElement = this.getButtonParent($currentTarget); diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js b/app/assets/javascripts/filtered_search/dropdown_utils.js index b52081df646..a5a6b56a0d3 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js @@ -80,30 +80,48 @@ } // Determines the full search query (visual tokens + input) - static getSearchQuery() { - const tokensContainer = document.querySelector('.tokens-container'); + static getSearchQuery(untilInput = false) { + const tokens = [].slice.call(document.querySelectorAll('.tokens-container li')); const values = []; - [].forEach.call(tokensContainer.querySelectorAll('.js-visual-token'), (token) => { - const name = token.querySelector('.name'); - const value = token.querySelector('.value'); - const symbol = value && value.dataset.symbol ? value.dataset.symbol : ''; - let valueText = ''; + if (untilInput) { + const inputIndex = _.findIndex(tokens, t => t.classList.contains('input-token')); + // Add one to include input-token to the tokens array + tokens.splice(inputIndex + 1); + } - if (value && value.innerText) { - valueText = value.innerText; - } - - if (token.className.indexOf('filtered-search-token') !== -1) { - values.push(`${name.innerText.toLowerCase()}:${symbol}${valueText}`); - } else { - values.push(name.innerText); + tokens.forEach((token) => { + if (token.classList.contains('js-visual-token')) { + const name = token.querySelector('.name'); + const value = token.querySelector('.value'); + const symbol = value && value.dataset.symbol ? value.dataset.symbol : ''; + let valueText = ''; + + if (value && value.innerText) { + valueText = value.innerText; + } + + if (token.className.indexOf('filtered-search-token') !== -1) { + values.push(`${name.innerText.toLowerCase()}:${symbol}${valueText}`); + } else { + values.push(name.innerText); + } + } else if (token.classList.contains('input-token')) { + const { isLastVisualTokenValid } = + gl.FilteredSearchVisualTokens.getLastVisualTokenBeforeInput(); + + const input = document.querySelector('.filtered-search'); + const inputValue = input && input.value; + + if (isLastVisualTokenValid) { + values.push(inputValue); + } else { + const previous = values.pop(); + values.push(`${previous}${inputValue}`); + } } }); - const input = document.querySelector('.filtered-search'); - values.push(input && input.value); - return values.join(' '); } diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js index 608c65c78a4..e1a97070439 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js @@ -139,7 +139,7 @@ } setDropdown() { - const query = gl.DropdownUtils.getSearchQuery(); + const query = gl.DropdownUtils.getSearchQuery(true); const { lastToken, searchToken } = this.tokenizer.processTokens(query); if (this.currentDropdown) { diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js index 58a984048de..638fe744668 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js @@ -363,10 +363,13 @@ tokenChange() { const dropdown = this.dropdownManager.mapping[this.dropdownManager.currentDropdown]; - const currentDropdownRef = dropdown.reference; - this.setDropdownWrapper(); - currentDropdownRef.dispatchInputEvent(); + if (dropdown) { + const currentDropdownRef = dropdown.reference; + + this.setDropdownWrapper(); + currentDropdownRef.dispatchInputEvent(); + } } } diff --git a/app/assets/javascripts/issue.js b/app/assets/javascripts/issue.js index 52457f70d90..ef4029a8623 100644 --- a/app/assets/javascripts/issue.js +++ b/app/assets/javascripts/issue.js @@ -5,131 +5,125 @@ require('./flash'); require('vendor/jquery.waitforimages'); require('./task_list'); -(function() { - var bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; }; - - this.Issue = (function() { - function Issue() { - this.submitNoteForm = bind(this.submitNoteForm, this); - if ($('a.btn-close').length) { - this.taskList = new gl.TaskList({ - dataType: 'issue', - fieldName: 'description', - selector: '.detail-page-description', - onSuccess: (result) => { - document.querySelector('#task_status').innerText = result.task_status; - document.querySelector('#task_status_short').innerText = result.task_status_short; - } - }); - this.initIssueBtnEventListeners(); - } - this.initMergeRequests(); - this.initRelatedBranches(); - this.initCanCreateBranch(); +class Issue { + constructor() { + if ($('a.btn-close').length) { + this.taskList = new gl.TaskList({ + dataType: 'issue', + fieldName: 'description', + selector: '.detail-page-description', + onSuccess: (result) => { + document.querySelector('#task_status').innerText = result.task_status; + document.querySelector('#task_status_short').innerText = result.task_status_short; + } + }); + Issue.initIssueBtnEventListeners(); } + Issue.initMergeRequests(); + Issue.initRelatedBranches(); + Issue.initCanCreateBranch(); + } - Issue.prototype.initIssueBtnEventListeners = function() { - var _this, issueFailMessage; - _this = this; - issueFailMessage = 'Unable to update this issue at this time.'; - return $('a.btn-close, a.btn-reopen').on('click', function(e) { - var $this, isClose, shouldSubmit, url; - e.preventDefault(); - e.stopImmediatePropagation(); - $this = $(this); - isClose = $this.hasClass('btn-close'); - shouldSubmit = $this.hasClass('btn-comment'); - if (shouldSubmit) { - _this.submitNoteForm($this.closest('form')); - } - $this.prop('disabled', true); - url = $this.attr('href'); - return $.ajax({ - type: 'PUT', - url: url, - error: function(jqXHR, textStatus, errorThrown) { - var issueStatus; - issueStatus = isClose ? 'close' : 'open'; - return new Flash(issueFailMessage, 'alert'); - }, - success: function(data, textStatus, jqXHR) { - if ('id' in data) { - $(document).trigger('issuable:change'); - const currentTotal = Number($('.issue_counter').text()); - if (isClose) { - $('a.btn-close').addClass('hidden'); - $('a.btn-reopen').removeClass('hidden'); - $('div.status-box-closed').removeClass('hidden'); - $('div.status-box-open').addClass('hidden'); - $('.issue_counter').text(currentTotal - 1); - } else { - $('a.btn-reopen').addClass('hidden'); - $('a.btn-close').removeClass('hidden'); - $('div.status-box-closed').addClass('hidden'); - $('div.status-box-open').removeClass('hidden'); - $('.issue_counter').text(currentTotal + 1); - } + static initIssueBtnEventListeners() { + var issueFailMessage; + issueFailMessage = 'Unable to update this issue at this time.'; + return $('a.btn-close, a.btn-reopen').on('click', function(e) { + var $this, isClose, shouldSubmit, url; + e.preventDefault(); + e.stopImmediatePropagation(); + $this = $(this); + isClose = $this.hasClass('btn-close'); + shouldSubmit = $this.hasClass('btn-comment'); + if (shouldSubmit) { + Issue.submitNoteForm($this.closest('form')); + } + $this.prop('disabled', true); + url = $this.attr('href'); + return $.ajax({ + type: 'PUT', + url: url, + error: function(jqXHR, textStatus, errorThrown) { + var issueStatus; + issueStatus = isClose ? 'close' : 'open'; + return new Flash(issueFailMessage, 'alert'); + }, + success: function(data, textStatus, jqXHR) { + if ('id' in data) { + $(document).trigger('issuable:change'); + const currentTotal = Number($('.issue_counter').text()); + if (isClose) { + $('a.btn-close').addClass('hidden'); + $('a.btn-reopen').removeClass('hidden'); + $('div.status-box-closed').removeClass('hidden'); + $('div.status-box-open').addClass('hidden'); + $('.issue_counter').text(currentTotal - 1); } else { - new Flash(issueFailMessage, 'alert'); + $('a.btn-reopen').addClass('hidden'); + $('a.btn-close').removeClass('hidden'); + $('div.status-box-closed').addClass('hidden'); + $('div.status-box-open').removeClass('hidden'); + $('.issue_counter').text(currentTotal + 1); } - return $this.prop('disabled', false); + } else { + new Flash(issueFailMessage, 'alert'); } - }); + return $this.prop('disabled', false); + } }); - }; + }); + } - Issue.prototype.submitNoteForm = function(form) { - var noteText; - noteText = form.find("textarea.js-note-text").val(); - if (noteText.trim().length > 0) { - return form.submit(); - } - }; + static submitNoteForm(form) { + var noteText; + noteText = form.find("textarea.js-note-text").val(); + if (noteText.trim().length > 0) { + return form.submit(); + } + } - Issue.prototype.initMergeRequests = function() { - var $container; - $container = $('#merge-requests'); - return $.getJSON($container.data('url')).error(function() { - return new Flash('Failed to load referenced merge requests', 'alert'); - }).success(function(data) { - if ('html' in data) { - return $container.html(data.html); - } - }); - }; + static initMergeRequests() { + var $container; + $container = $('#merge-requests'); + return $.getJSON($container.data('url')).error(function() { + return new Flash('Failed to load referenced merge requests', 'alert'); + }).success(function(data) { + if ('html' in data) { + return $container.html(data.html); + } + }); + } - Issue.prototype.initRelatedBranches = function() { - var $container; - $container = $('#related-branches'); - return $.getJSON($container.data('url')).error(function() { - return new Flash('Failed to load related branches', 'alert'); - }).success(function(data) { - if ('html' in data) { - return $container.html(data.html); - } - }); - }; + static initRelatedBranches() { + var $container; + $container = $('#related-branches'); + return $.getJSON($container.data('url')).error(function() { + return new Flash('Failed to load related branches', 'alert'); + }).success(function(data) { + if ('html' in data) { + return $container.html(data.html); + } + }); + } - Issue.prototype.initCanCreateBranch = function() { - var $container; - $container = $('#new-branch'); - // If the user doesn't have the required permissions the container isn't - // rendered at all. - if ($container.length === 0) { - return; + static initCanCreateBranch() { + var $container; + $container = $('#new-branch'); + // If the user doesn't have the required permissions the container isn't + // rendered at all. + if ($container.length === 0) { + return; + } + return $.getJSON($container.data('path')).error(function() { + $container.find('.unavailable').show(); + return new Flash('Failed to check if a new branch can be created.', 'alert'); + }).success(function(data) { + if (data.can_create_branch) { + $container.find('.available').show(); + } else { + return $container.find('.unavailable').show(); } - return $.getJSON($container.data('path')).error(function() { - $container.find('.unavailable').show(); - return new Flash('Failed to check if a new branch can be created.', 'alert'); - }).success(function(data) { - if (data.can_create_branch) { - $container.find('.available').show(); - } else { - return $container.find('.unavailable').show(); - } - }); - }; + }); + } +} - return Issue; - })(); -}).call(window); +export default Issue; diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index ae4dd64424c..79164edff0e 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -342,11 +342,11 @@ require('./zen_mode'); var notesHolders = $this.closest('.diff-file').find('.notes_holder'); $this.toggleClass('active'); if ($this.hasClass('active')) { - notesHolders.show().find('.hide').show(); + notesHolders.show().find('.hide, .content').show(); } else { - notesHolders.hide(); + notesHolders.hide().find('.content').hide(); } - $this.trigger('blur'); + $(document).trigger('toggle.comments'); return e.preventDefault(); }); $document.off('click', '.js-confirm-danger'); diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index df7a7d2a459..eeab69da941 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -312,7 +312,7 @@ require('./task_list'); */ Notes.prototype.renderDiscussionNote = function(note) { - var discussionContainer, form, note_html, row; + var discussionContainer, form, note_html, row, lineType, diffAvatarContainer; if (!this.isNewNote(note)) { return; } @@ -322,6 +322,8 @@ require('./task_list'); form = $("#new-discussion-note-form-" + note.original_discussion_id); } row = form.closest("tr"); + lineType = this.isParallelView() ? form.find('#line_type').val() : 'old'; + diffAvatarContainer = row.prevAll('.line_holder').first().find('.js-avatar-container.' + lineType + '_line'); note_html = $(note.html); note_html.renderGFM(); // is this the first note of discussion? @@ -330,10 +332,26 @@ require('./task_list'); discussionContainer = $(".notes[data-discussion-id='" + note.original_discussion_id + "']"); } if (discussionContainer.length === 0) { - // insert the note and the reply button after the temp row - row.after(note.diff_discussion_html); - // remove the note (will be added again below) - row.next().find(".note").remove(); + if (!this.isParallelView() || row.hasClass('js-temp-notes-holder')) { + // insert the note and the reply button after the temp row + row.after(note.diff_discussion_html); + + // remove the note (will be added again below) + row.next().find(".note").remove(); + } else { + // Merge new discussion HTML in + var $discussion = $(note.diff_discussion_html); + var $notes = $discussion.find('.notes[data-discussion-id="' + note.discussion_id + '"]'); + var contentContainerClass = '.' + $notes.closest('.notes_content') + .attr('class') + .split(' ') + .join('.'); + + // remove the note (will be added again below) + $notes.find('.note').remove(); + + row.find(contentContainerClass + ' .content').append($notes.closest('.content').children()); + } // Before that, the container didn't exist discussionContainer = $(".notes[data-discussion-id='" + note.discussion_id + "']"); // Add note to 'Changes' page discussions @@ -347,14 +365,40 @@ require('./task_list'); discussionContainer.append(note_html); } - if (typeof gl.diffNotesCompileComponents !== 'undefined') { + if (typeof gl.diffNotesCompileComponents !== 'undefined' && note.discussion_id) { gl.diffNotesCompileComponents(); + this.renderDiscussionAvatar(diffAvatarContainer, note); } gl.utils.localTimeAgo($('.js-timeago'), false); return this.updateNotesCount(1); }; + Notes.prototype.getLineHolder = function(changesDiscussionContainer) { + return $(changesDiscussionContainer).closest('.notes_holder') + .prevAll('.line_holder') + .first() + .get(0); + }; + + Notes.prototype.renderDiscussionAvatar = function(diffAvatarContainer, note) { + var commentButton = diffAvatarContainer.find('.js-add-diff-note-button'); + var avatarHolder = diffAvatarContainer.find('.diff-comment-avatar-holders'); + + if (!avatarHolder.length) { + avatarHolder = document.createElement('diff-note-avatars'); + avatarHolder.setAttribute('discussion-id', note.discussion_id); + + diffAvatarContainer.append(avatarHolder); + + gl.diffNotesCompileComponents(); + } + + if (commentButton.length) { + commentButton.remove(); + } + }; + /* Called in response the main target form has been successfully submitted. @@ -592,9 +636,14 @@ require('./task_list'); */ Notes.prototype.removeNote = function(e) { - var noteId; - noteId = $(e.currentTarget).closest(".note").attr("id"); - $(".note[id='" + noteId + "']").each((function(_this) { + var noteElId, noteId, dataNoteId, $note, lineHolder; + $note = $(e.currentTarget).closest('.note'); + noteElId = $note.attr('id'); + noteId = $note.attr('data-note-id'); + lineHolder = $(e.currentTarget).closest('.notes[data-discussion-id]') + .closest('.notes_holder') + .prev('.line_holder'); + $(".note[id='" + noteElId + "']").each((function(_this) { // A same note appears in the "Discussion" and in the "Changes" tab, we have // to remove all. Using $(".note[id='noteId']") ensure we get all the notes, // where $("#noteId") would return only one. @@ -604,17 +653,26 @@ require('./task_list'); notes = note.closest(".notes"); if (typeof gl.diffNotesCompileComponents !== 'undefined') { - if (gl.diffNoteApps[noteId]) { - gl.diffNoteApps[noteId].$destroy(); + if (gl.diffNoteApps[noteElId]) { + gl.diffNoteApps[noteElId].$destroy(); } } + note.remove(); + // check if this is the last note for this line - if (notes.find(".note").length === 1) { + if (notes.find(".note").length === 0) { + var notesTr = notes.closest("tr"); + // "Discussions" tab notes.closest(".timeline-entry").remove(); - // "Changes" tab / commit view - notes.closest("tr").remove(); + + if (!_this.isParallelView() || notesTr.find('.note').length === 0) { + // "Changes" tab / commit view + notesTr.remove(); + } else { + notes.closest('.content').empty(); + } } return note.remove(); }; @@ -707,15 +765,16 @@ require('./task_list'); */ Notes.prototype.addDiffNote = function(e) { - var $link, addForm, hasNotes, lineType, newForm, nextRow, noteForm, notesContent, notesContentSelector, replyButton, row, rowCssToAdd, targetContent; + var $link, addForm, hasNotes, lineType, newForm, nextRow, noteForm, notesContent, notesContentSelector, replyButton, row, rowCssToAdd, targetContent, isDiffCommentAvatar; e.preventDefault(); - $link = $(e.currentTarget); + $link = $(e.currentTarget || e.target); row = $link.closest("tr"); nextRow = row.next(); hasNotes = nextRow.is(".notes_holder"); addForm = false; notesContentSelector = ".notes_content"; rowCssToAdd = "<tr class=\"notes_holder js-temp-notes-holder\"><td class=\"notes_line\" colspan=\"2\"></td><td class=\"notes_content\"><div class=\"content\"></div></td></tr>"; + isDiffCommentAvatar = $link.hasClass('js-diff-comment-avatar'); // In parallel view, look inside the correct left/right pane if (this.isParallelView()) { lineType = $link.data("lineType"); @@ -723,7 +782,9 @@ require('./task_list'); rowCssToAdd = "<tr class=\"notes_holder js-temp-notes-holder\"><td class=\"notes_line old\"></td><td class=\"notes_content parallel old\"><div class=\"content\"></div></td><td class=\"notes_line new\"></td><td class=\"notes_content parallel new\"><div class=\"content\"></div></td></tr>"; } notesContentSelector += " .content"; - if (hasNotes) { + notesContent = nextRow.find(notesContentSelector); + + if (hasNotes && !isDiffCommentAvatar) { nextRow.show(); notesContent = nextRow.find(notesContentSelector); if (notesContent.length) { @@ -740,13 +801,21 @@ require('./task_list'); } } } - } else { + } else if (!isDiffCommentAvatar) { // add a notes row and insert the form row.after(rowCssToAdd); nextRow = row.next(); notesContent = nextRow.find(notesContentSelector); addForm = true; + } else { + nextRow.show(); + notesContent.toggle(!notesContent.is(':visible')); + + if (!nextRow.find('.content:not(:empty)').is(':visible')) { + nextRow.hide(); + } } + if (addForm) { newForm = this.formClone.clone(); newForm.appendTo(notesContent); diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 887ab481de4..fe8b37d2c6e 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -159,12 +159,12 @@ li { text-align: left; list-style: none; - padding: 0 8px; + padding: 0 10px; } .divider { height: 1px; - margin: 8px; + margin: 6px 10px; padding: 0; background-color: $dropdown-divider-color; } @@ -181,7 +181,7 @@ display: block; position: relative; padding: 5px 8px; - color: $dropdown-link-color; + color: $gl-text-color; line-height: initial; text-overflow: ellipsis; border-radius: 2px; @@ -218,11 +218,12 @@ } .dropdown-header { - color: $gl-text-color-secondary; + color: $gl-text-color; font-size: 13px; + font-weight: 600; line-height: 22px; text-transform: capitalize; - padding: 0 10px; + padding: 0 16px; } .separator + .dropdown-header { @@ -325,14 +326,17 @@ .dropdown-menu-selectable { a { - padding-left: 25px; + padding-left: 26px; &.is-indeterminate, &.is-active { + font-weight: 600; + color: $gl-text-color; + &::before { position: absolute; - left: 5px; - top: 8px; + left: 6px; + top: 6px; font: normal normal normal 14px/1 FontAwesome; font-size: inherit; text-rendering: auto; @@ -354,7 +358,7 @@ .dropdown-title { position: relative; - padding: 0 25px 10px; + padding: 2px 25px 10px; margin: 0 10px 10px; font-weight: 600; line-height: 1; @@ -384,7 +388,7 @@ right: 5px; width: 20px; height: 20px; - top: -3px; + top: -1px; } .dropdown-menu-back { diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss index 674d3bb45aa..ea45aaa0253 100644 --- a/app/assets/stylesheets/framework/nav.scss +++ b/app/assets/stylesheets/framework/nav.scss @@ -294,7 +294,7 @@ .nav-control { @media (max-width: $screen-sm-max) { - margin-right: 75px; + margin-right: 2px; } } } diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index 5d0c247dea8..eab79c2a481 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -113,6 +113,10 @@ td.line_content.parallel { width: 46%; } + + .add-diff-note { + margin-left: -55px; + } } .old_line, @@ -490,3 +494,103 @@ } } } + +.diff-comment-avatar-holders { + position: absolute; + height: 19px; + width: 19px; + margin-left: -15px; + + &:hover { + .diff-comment-avatar, + .diff-comments-more-count { + @for $i from 1 through 4 { + $x-pos: 14px; + + &:nth-child(#{$i}) { + @if $i == 4 { + $x-pos: 14.5px; + } + + transform: translateX((($i * $x-pos) - $x-pos)); + + &:hover { + transform: translateX((($i * $x-pos) - $x-pos)) scale(1.2); + } + } + } + } + + .diff-comments-more-count { + padding-left: 2px; + padding-right: 2px; + width: auto; + } + } +} + +.diff-comment-avatar, +.diff-comments-more-count { + position: absolute; + left: 0; + width: 19px; + height: 19px; + margin-right: 0; + border-color: $white-light; + cursor: pointer; + transition: all .1s ease-out; + + @for $i from 1 through 4 { + &:nth-child(#{$i}) { + z-index: (4 - $i); + } + } +} + +.diff-comments-more-count { + width: 19px; + min-width: 19px; + padding-left: 0; + padding-right: 0; + overflow: hidden; +} + +.diff-comments-more-count, +.diff-notes-collapse { + background-color: $gray-darkest; + color: $white-light; + border: 1px solid $white-light; + border-radius: 1em; + font-family: $regular_font; + font-size: 9px; + line-height: 17px; + text-align: center; +} + +.diff-notes-collapse { + position: relative; + width: 19px; + height: 19px; + padding: 0; + transition: transform .1s ease-out; + + svg { + position: absolute; + left: 50%; + top: 50%; + margin-left: -5.5px; + margin-top: -5.5px; + } + + path { + fill: $white-light; + } + + &:hover { + transform: scale(1.2); + } + + &:focus { + outline: 0; + } +} diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 2c2c408b035..a7cdca9ba2e 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -15,6 +15,8 @@ module CiStatusHelper 'passed' when 'success_with_warnings' 'passed with warnings' + when 'manual' + 'waiting for manual action' else status end diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb index 710218082f2..243ef39ef61 100644 --- a/app/helpers/preferences_helper.rb +++ b/app/helpers/preferences_helper.rb @@ -36,7 +36,7 @@ module PreferencesHelper def project_view_choices [ ['Files and Readme (default)', :files], - ['Activity view', :activity] + ['Activity', :activity] ] end diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index 9a4e423f896..10867140d4f 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -6,10 +6,8 @@ .top-area = render 'shared/issuable/nav', type: :issues .nav-controls - = link_to params.merge(rss_url_options), class: 'btn' do + = link_to params.merge(rss_url_options), class: 'btn has-tooltip', title: 'Subscribe' do = icon('rss') - %span.icon-label - Subscribe = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" = render 'shared/issuable/filter', type: :issues diff --git a/app/views/dashboard/projects/starred.html.haml b/app/views/dashboard/projects/starred.html.haml index 70705923d42..162ae153b1c 100644 --- a/app/views/dashboard/projects/starred.html.haml +++ b/app/views/dashboard/projects/starred.html.haml @@ -6,7 +6,7 @@ - if @last_push = render "events/event_last_push", event: @last_push -- if @projects.any? +- if @projects.any? || params[:filter_projects] = render 'projects' - else %h3 You don't have starred projects yet diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml index 951f03083bf..a039756c7e2 100644 --- a/app/views/devise/sessions/two_factor.html.haml +++ b/app/views/devise/sessions/two_factor.html.haml @@ -1,6 +1,6 @@ - if inject_u2f_api? - content_for :page_specific_javascripts do - = page_specific_javascript_tag('u2f.js') + = page_specific_javascript_bundle_tag('u2f') %div = render 'devise/shared/tab_single', tab_title: 'Two-Factor Authentication' diff --git a/app/views/discussions/_diff_discussion.html.haml b/app/views/discussions/_diff_discussion.html.haml index 2deadbeeceb..ee452add394 100644 --- a/app/views/discussions/_diff_discussion.html.haml +++ b/app/views/discussions/_diff_discussion.html.haml @@ -2,5 +2,5 @@ %tr.notes_holder{ class: ('hide' unless expanded) } %td.notes_line{ colspan: 2 } %td.notes_content - .content + .content{ class: ('hide' unless expanded) } = render "discussions/notes", discussion: discussion diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml index 558a1d56151..7ade5f00d47 100644 --- a/app/views/profiles/two_factor_auths/show.html.haml +++ b/app/views/profiles/two_factor_auths/show.html.haml @@ -4,7 +4,7 @@ - if inject_u2f_api? - content_for :page_specific_javascripts do - = page_specific_javascript_tag('u2f.js') + = page_specific_javascript_bundle_tag('u2f') .row.prepend-top-default .col-lg-3 @@ -96,4 +96,3 @@ :javascript var button = "<a class='btn btn-xs btn-warning pull-right' data-method='patch' href='#{skip_profile_two_factor_auth_path}'>Configure it later</a>"; $(".flash-alert").append(button); - diff --git a/app/views/projects/deployments/_actions.haml b/app/views/projects/deployments/_actions.haml index a680b1ca017..506246f2ee6 100644 --- a/app/views/projects/deployments/_actions.haml +++ b/app/views/projects/deployments/_actions.haml @@ -1,9 +1,9 @@ - if can?(current_user, :create_deployment, deployment) - actions = deployment.manual_actions - if actions.present? - .inline + .btn-group .dropdown - %a.dropdown-new.btn.btn-default{ type: 'button', 'data-toggle' => 'dropdown' } + %button.dropdown.dropdown-new.btn.btn-default{ type: 'button', 'data-toggle' => 'dropdown' } = custom_icon('icon_play') = icon('caret-down') %ul.dropdown-menu.dropdown-menu-align-right @@ -12,4 +12,3 @@ = link_to [:play, @project.namespace.becomes(Namespace), @project, action], method: :post, rel: 'nofollow' do = custom_icon('icon_play') %span= action.name.humanize - diff --git a/app/views/projects/deployments/_deployment.html.haml b/app/views/projects/deployments/_deployment.html.haml index c468202569f..260c9023daf 100644 --- a/app/views/projects/deployments/_deployment.html.haml +++ b/app/views/projects/deployments/_deployment.html.haml @@ -17,6 +17,6 @@ #{time_ago_with_tooltip(deployment.created_at)} %td.hidden-xs - .pull-right + .pull-right.btn-group = render 'projects/deployments/actions', deployment: deployment = render 'projects/deployments/rollback', deployment: deployment diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml index cd18ba2ed00..ed279cfe168 100644 --- a/app/views/projects/diffs/_line.html.haml +++ b/app/views/projects/diffs/_line.html.haml @@ -1,8 +1,11 @@ - email = local_assigns.fetch(:email, false) - plain = local_assigns.fetch(:plain, false) +- discussions = local_assigns.fetch(:discussions, nil) - type = line.type - line_code = diff_file.line_code(line) -%tr.line_holder{ plain ? { class: type} : { class: type, id: line_code } } +- if discussions && !line.meta? + - discussion = discussions[line_code] +%tr.line_holder{ class: type, id: (line_code unless plain) } - case type - when 'match' = diff_match_line line.old_pos, line.new_pos, text: line.text @@ -11,12 +14,14 @@ %td.new_line.diff-line-num %td.line_content.match= line.text - else - %td.old_line.diff-line-num{ class: type, data: { linenumber: line.old_pos } } + %td.old_line.diff-line-num.js-avatar-container{ class: type, data: { linenumber: line.old_pos } } - link_text = type == "new" ? " " : line.old_pos - if plain = link_text - else %a{ href: "##{line_code}", data: { linenumber: link_text } } + - if discussion && !plain + %diff-note-avatars{ "discussion-id" => discussion.id } %td.new_line.diff-line-num{ class: type, data: { linenumber: line.new_pos } } - link_text = type == "old" ? " " : line.new_pos - if plain @@ -29,9 +34,6 @@ - else = diff_line_content(line.text) -- discussions = local_assigns.fetch(:discussions, nil) -- if discussions && !line.meta? - - discussion = discussions[line_code] - - if discussion - - discussion_expanded = local_assigns.fetch(:discussion_expanded, discussion.expanded?) - = render "discussions/diff_discussion", discussion: discussion, expanded: discussion_expanded +- if discussion + - discussion_expanded = local_assigns.fetch(:discussion_expanded, discussion.expanded?) + = render "discussions/diff_discussion", discussion: discussion, expanded: discussion_expanded diff --git a/app/views/projects/diffs/_parallel_view.html.haml b/app/views/projects/diffs/_parallel_view.html.haml index 997bf0fc560..6448748113b 100644 --- a/app/views/projects/diffs/_parallel_view.html.haml +++ b/app/views/projects/diffs/_parallel_view.html.haml @@ -4,6 +4,9 @@ - diff_file.parallel_diff_lines.each do |line| - left = line[:left] - right = line[:right] + - last_line = right.new_pos if right + - unless @diff_notes_disabled + - discussion_left, discussion_right = parallel_diff_discussions(left, right, diff_file) %tr.line_holder.parallel - if left - case left.type @@ -15,8 +18,10 @@ - else - left_line_code = diff_file.line_code(left) - left_position = diff_file.position(left) - %td.old_line.diff-line-num{ id: left_line_code, class: left.type, data: { linenumber: left.old_pos } } + %td.old_line.diff-line-num.js-avatar-container{ id: left_line_code, class: left.type, data: { linenumber: left.old_pos } } %a{ href: "##{left_line_code}", data: { linenumber: left.old_pos } } + - if discussion_left + %diff-note-avatars{ "discussion-id" => discussion_left.id } %td.line_content.parallel.noteable_line{ class: left.type, data: diff_view_line_data(left_line_code, left_position, 'old') }= diff_line_content(left.text) - else %td.old_line.diff-line-num.empty-cell @@ -32,17 +37,17 @@ - else - right_line_code = diff_file.line_code(right) - right_position = diff_file.position(right) - %td.new_line.diff-line-num{ id: right_line_code, class: right.type, data: { linenumber: right.new_pos } } + %td.new_line.diff-line-num.js-avatar-container{ id: right_line_code, class: right.type, data: { linenumber: right.new_pos } } %a{ href: "##{right_line_code}", data: { linenumber: right.new_pos } } + - if discussion_right + %diff-note-avatars{ "discussion-id" => discussion_right.id } %td.line_content.parallel.noteable_line{ class: right.type, data: diff_view_line_data(right_line_code, right_position, 'new') }= diff_line_content(right.text) - else %td.old_line.diff-line-num.empty-cell %td.line_content.parallel - - unless @diff_notes_disabled - - discussion_left, discussion_right = parallel_diff_discussions(left, right, diff_file) - - if discussion_left || discussion_right - = render "discussions/parallel_diff_discussion", discussion_left: discussion_left, discussion_right: discussion_right + - if discussion_left || discussion_right + = render "discussions/parallel_diff_discussion", discussion_left: discussion_left, discussion_right: discussion_right - if !diff_file.new_file && !diff_file.deleted_file && diff_file.diff_lines.any? - last_line = diff_file.diff_lines.last - if last_line.new_pos < total_lines diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml index 29a98f23b88..f463a429f65 100644 --- a/app/views/projects/environments/show.html.haml +++ b/app/views/projects/environments/show.html.haml @@ -16,7 +16,7 @@ - if can?(current_user, :create_deployment, @environment) && @environment.can_stop? = link_to 'Stop', stop_namespace_project_environment_path(@project.namespace, @project, @environment), data: { confirm: 'Are you sure you want to stop this environment?' }, class: 'btn btn-danger', method: :post - .deployments-container + .environments-container - if @deployments.blank? .blank-state.blank-state-no-icon %h2.blank-state-title diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index a73e8f345e0..a7618370a5d 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -2,7 +2,7 @@ - return if note.cross_reference_not_visible_for?(current_user) - note_editable = note_editable?(note) -%li.timeline-entry{ id: dom_id(note), class: ["note", "note-row-#{note.id}", ('system-note' if note.system)], data: {author_id: note.author.id, editable: note_editable} } +%li.timeline-entry{ id: dom_id(note), class: ["note", "note-row-#{note.id}", ('system-note' if note.system)], data: {author_id: note.author.id, editable: note_editable, note_id: note.id} } .timeline-entry-inner .timeline-icon %a{ href: user_path(note.author) } @@ -30,11 +30,15 @@ - if note.resolvable? - can_resolve = can?(current_user, :resolve_note, note) - %resolve-btn{ "discussion-id" => "#{note.discussion_id}", + %resolve-btn{ "project-path" => project_path(note.project), + "discussion-id" => note.discussion_id, ":note-id" => note.id, ":resolved" => note.resolved?, ":can-resolve" => can_resolve, - "resolved-by" => "#{note.resolved_by.try(:name)}", + ":author-name" => "'#{j(note.author.name)}'", + "author-avatar" => note.author.avatar_url, + ":note-truncated" => "'#{truncate(note.note, length: 17)}'", + ":resolved-by" => "'#{j(note.resolved_by.try(:name))}'", "v-show" => "#{can_resolve || note.resolved?}", "inline-template" => true, "ref" => "note_#{note.id}" } diff --git a/app/views/shared/icons/_collapse.svg.erb b/app/views/shared/icons/_collapse.svg.erb new file mode 100644 index 00000000000..917753fb343 --- /dev/null +++ b/app/views/shared/icons/_collapse.svg.erb @@ -0,0 +1 @@ +<svg width="<%= size %>" height="<%= size %>" viewBox="0 0 9 13"><path d="M2.57568253,6.49866948 C2.50548852,6.57199715 2.44637866,6.59708255 2.39835118,6.57392645 C2.3503237,6.55077034 2.32631032,6.48902165 2.32631032,6.38867852 L2.32631032,-2.13272614 C2.32631032,-2.23306927 2.3503237,-2.29481796 2.39835118,-2.31797406 C2.44637866,-2.34113017 2.50548852,-2.31604477 2.57568253,-2.24271709 L6.51022184,1.86747129 C6.53977721,1.8983461 6.56379059,1.93500939 6.5822627,1.97746225 L6.5822627,2.27849013 C6.56379059,2.31708364 6.53977721,2.35374693 6.51022184,2.38848109 L2.57568253,6.49866948 Z" transform="translate(4.454287, 2.127976) rotate(90.000000) translate(-4.454287, -2.127976) "></path><path d="M3.74312342,2.09553332 C3.74312342,1.99519019 3.77821989,1.9083561 3.8484139,1.83502843 C3.91860791,1.76170075 4.00173115,1.72503747 4.09778611,1.72503747 L4.80711151,1.72503747 C4.90316647,1.72503747 4.98628971,1.76170075 5.05648372,1.83502843 C5.12667773,1.9083561 5.16177421,1.99519019 5.16177421,2.09553332 L5.16177421,10.2464421 C5.16177421,10.3467853 5.12667773,10.4336194 5.05648372,10.506947 C4.98628971,10.5802747 4.90316647,10.616938 4.80711151,10.616938 L4.09778611,10.616938 C4.00173115,10.616938 3.91860791,10.5802747 3.8484139,10.506947 C3.77821989,10.4336194 3.74312342,10.3467853 3.74312342,10.2464421 L3.74312342,2.09553332 Z" transform="translate(4.452449, 6.170988) rotate(-90.000000) translate(-4.452449, -6.170988) "></path><path d="M2.57568253,14.6236695 C2.50548852,14.6969971 2.44637866,14.7220826 2.39835118,14.6989264 C2.3503237,14.6757703 2.32631032,14.6140216 2.32631032,14.5136785 L2.32631032,5.99227386 C2.32631032,5.89193073 2.3503237,5.83018204 2.39835118,5.80702594 C2.44637866,5.78386983 2.50548852,5.80895523 2.57568253,5.88228291 L6.51022184,9.99247129 C6.53977721,10.0233461 6.56379059,10.0600094 6.5822627,10.1024622 L6.5822627,10.4034901 C6.56379059,10.4420836 6.53977721,10.4787469 6.51022184,10.5134811 L2.57568253,14.6236695 Z" transform="translate(4.454287, 10.252976) scale(1, -1) rotate(90.000000) translate(-4.454287, -10.252976) "></path></svg> diff --git a/changelogs/unreleased/26202-change-dropdown-style-slightly.yml b/changelogs/unreleased/26202-change-dropdown-style-slightly.yml new file mode 100644 index 00000000000..827224abf5a --- /dev/null +++ b/changelogs/unreleased/26202-change-dropdown-style-slightly.yml @@ -0,0 +1,4 @@ +--- +title: Changed dropdown style slightly +merge_request: +author: diff --git a/changelogs/unreleased/28402-fix-starred-projects-filter-wrong-message-on-no-results.yml b/changelogs/unreleased/28402-fix-starred-projects-filter-wrong-message-on-no-results.yml new file mode 100644 index 00000000000..dd94b3fe663 --- /dev/null +++ b/changelogs/unreleased/28402-fix-starred-projects-filter-wrong-message-on-no-results.yml @@ -0,0 +1,4 @@ +--- +title: Fix wrong message on starred projects filtering +merge_request: +author: George Andrinopoulos diff --git a/changelogs/unreleased/29034-fix-github-importer.yml b/changelogs/unreleased/29034-fix-github-importer.yml new file mode 100644 index 00000000000..6d08db3d55d --- /dev/null +++ b/changelogs/unreleased/29034-fix-github-importer.yml @@ -0,0 +1,4 @@ +--- +title: Fix name colision when importing GitHub pull requests from forked repositories +merge_request: 9719 +author: diff --git a/changelogs/unreleased/29162-refactor-dropdown-milestone-spec.yml b/changelogs/unreleased/29162-refactor-dropdown-milestone-spec.yml new file mode 100644 index 00000000000..ad0c513f525 --- /dev/null +++ b/changelogs/unreleased/29162-refactor-dropdown-milestone-spec.yml @@ -0,0 +1,4 @@ +--- +title: Refactor dropdown_milestone_spec.rb +merge_request: +author: George Andrinopoulos diff --git a/changelogs/unreleased/es6-class-issue.yml b/changelogs/unreleased/es6-class-issue.yml new file mode 100644 index 00000000000..9d1c3ac7421 --- /dev/null +++ b/changelogs/unreleased/es6-class-issue.yml @@ -0,0 +1,4 @@ +--- +title: Convert Issue into ES6 class +merge_request: 9636 +author: winniehell diff --git a/config/application.rb b/config/application.rb index cdb93e50e66..1cc092c4da1 100644 --- a/config/application.rb +++ b/config/application.rb @@ -100,7 +100,6 @@ module Gitlab config.assets.precompile << "katex.js" config.assets.precompile << "xterm/xterm.css" config.assets.precompile << "lib/ace.js" - config.assets.precompile << "u2f.js" config.assets.precompile << "vendor/assets/fonts/*" # Version of your assets, change this if you want to expire all your assets diff --git a/config/webpack.config.js b/config/webpack.config.js index 7298e7109c6..ff5f1412261 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -40,6 +40,7 @@ var config = { protected_branches: './protected_branches/protected_branches_bundle.js', snippet: './snippet/snippet_bundle.js', terminal: './terminal/terminal_bundle.js', + u2f: ['vendor/u2f'], users: './users/users_bundle.js', vue_pipelines: './vue_pipelines_index/index.js', }, diff --git a/doc/README.md b/doc/README.md index 46a1ed0e148..57d85d770e7 100644 --- a/doc/README.md +++ b/doc/README.md @@ -19,7 +19,7 @@ - [Migrating from SVN](workflow/importing/migrating_from_svn.md) Convert a SVN repository to Git and GitLab. - [Permissions](user/permissions.md) Learn what each role in a project (external/guest/reporter/developer/master/owner) can do. - [Profile Settings](profile/README.md) -- [Project Services](user/project/integrations//project_services.md) Integrate a project with external services, such as CI and chat. +- [Project Services](user/project/integrations/project_services.md) Integrate a project with external services, such as CI and chat. - [Public access](public_access/public_access.md) Learn how you can allow public and internal access to projects. - [Snippets](user/snippets.md) Snippets allow you to create little bits of code. - [SSH](ssh/README.md) Setup your ssh keys and deploy keys for secure access to your projects. diff --git a/doc/administration/high_availability/database.md b/doc/administration/high_availability/database.md index e4f94eb7cb6..0a08591c3ce 100644 --- a/doc/administration/high_availability/database.md +++ b/doc/administration/high_availability/database.md @@ -16,7 +16,7 @@ If you use a cloud-managed service, or provide your own PostgreSQL: 1. Set up a `gitlab` username with a password of your choice. The `gitlab` user needs privileges to create the `gitlabhq_production` database. 1. Configure the GitLab application servers with the appropriate details. - This step is covered in [Configuring GitLab for HA](gitlab.md) + This step is covered in [Configuring GitLab for HA](gitlab.md). ## Configure using Omnibus @@ -105,6 +105,8 @@ If you use a cloud-managed service, or provide your own PostgreSQL: 1. Exit the database prompt by typing `\q` and Enter. 1. Exit the `gitlab-psql` user by running `exit` twice. 1. Run `sudo gitlab-ctl reconfigure` a final time. +1. Configure the GitLab application servers with the appropriate details. + This step is covered in [Configuring GitLab for HA](gitlab.md). --- diff --git a/doc/administration/high_availability/load_balancer.md b/doc/administration/high_availability/load_balancer.md index dad8e956c0e..3245988fc14 100644 --- a/doc/administration/high_availability/load_balancer.md +++ b/doc/administration/high_availability/load_balancer.md @@ -19,8 +19,8 @@ you need to use with GitLab. ## GitLab Pages Ports If you're using GitLab Pages you will need some additional port configurations. -GitLab Pages requires a separate VIP. Configure DNS to point the -`pages_external_url` from `/etc/gitlab/gitlab.rb` at the new VIP. See the +GitLab Pages requires a separate virtual IP address. Configure DNS to point the +`pages_external_url` from `/etc/gitlab/gitlab.rb` at the new virtual IP address. See the [GitLab Pages documentation][gitlab-pages] for more information. | LB Port | Backend Port | Protocol | @@ -32,7 +32,7 @@ GitLab Pages requires a separate VIP. Configure DNS to point the Some organizations have policies against opening SSH port 22. In this case, it may be helpful to configure an alternate SSH hostname that allows users -to use SSH on port 443. An alternate SSH hostname will require a new VIP +to use SSH on port 443. An alternate SSH hostname will require a new virtual IP address compared to the other GitLab HTTP configuration above. Configure DNS for an alternate SSH hostname such as altssh.gitlab.example.com. diff --git a/doc/user/project/container_registry.md b/doc/user/project/container_registry.md index 91b35c73b34..b6221620e58 100644 --- a/doc/user/project/container_registry.md +++ b/doc/user/project/container_registry.md @@ -249,4 +249,4 @@ Once the right permissions were set, the error will go away. [ce-4040]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4040 [docker-docs]: https://docs.docker.com/engine/userguide/intro/ -[private-docker]: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#using-a-private-docker-registry +[private-docker]: https://docs.gitlab.com/runner/configuration/advanced-configuration.html#using-a-private-container-registry diff --git a/features/support/capybara.rb b/features/support/capybara.rb index 47372df152d..a5fcbb65131 100644 --- a/features/support/capybara.rb +++ b/features/support/capybara.rb @@ -2,7 +2,7 @@ require 'spinach/capybara' require 'capybara/poltergeist' # Give CI some extra time -timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 90 : 15 +timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 30 : 10 Capybara.javascript_driver = :poltergeist Capybara.register_driver :poltergeist do |app| diff --git a/fixtures/emojis/emoji-unicode-version-map.json b/fixtures/emojis/emoji-unicode-version-map.json new file mode 100644 index 00000000000..5164fe39426 --- /dev/null +++ b/fixtures/emojis/emoji-unicode-version-map.json @@ -0,0 +1,2377 @@ +{ + "100": "6.0", + "1234": "6.0", + "grinning": "6.1", + "grin": "6.0", + "joy": "6.0", + "rofl": "9.0", + "rolling_on_the_floor_laughing": "9.0", + "smiley": "6.0", + "smile": "6.0", + "sweat_smile": "6.0", + "laughing": "6.0", + "satisfied": "6.0", + "wink": "6.0", + "blush": "6.0", + "yum": "6.0", + "sunglasses": "6.0", + "heart_eyes": "6.0", + "kissing_heart": "6.0", + "kissing": "6.1", + "kissing_smiling_eyes": "6.1", + "kissing_closed_eyes": "6.0", + "relaxed": "1.1", + "slight_smile": "7.0", + "slightly_smiling_face": "7.0", + "hugging": "8.0", + "hugging_face": "8.0", + "thinking": "8.0", + "thinking_face": "8.0", + "neutral_face": "6.0", + "expressionless": "6.1", + "no_mouth": "6.0", + "rolling_eyes": "8.0", + "face_with_rolling_eyes": "8.0", + "smirk": "6.0", + "persevere": "6.0", + "disappointed_relieved": "6.0", + "open_mouth": "6.1", + "zipper_mouth": "8.0", + "zipper_mouth_face": "8.0", + "hushed": "6.1", + "sleepy": "6.0", + "tired_face": "6.0", + "sleeping": "6.1", + "relieved": "6.0", + "nerd": "8.0", + "nerd_face": "8.0", + "stuck_out_tongue": "6.1", + "stuck_out_tongue_winking_eye": "6.0", + "stuck_out_tongue_closed_eyes": "6.0", + "drooling_face": "9.0", + "drool": "9.0", + "unamused": "6.0", + "sweat": "6.0", + "pensive": "6.0", + "confused": "6.1", + "upside_down": "8.0", + "upside_down_face": "8.0", + "money_mouth": "8.0", + "money_mouth_face": "8.0", + "astonished": "6.0", + "frowning2": "1.1", + "white_frowning_face": "1.1", + "slight_frown": "7.0", + "slightly_frowning_face": "7.0", + "confounded": "6.0", + "disappointed": "6.0", + "worried": "6.1", + "triumph": "6.0", + "cry": "6.0", + "sob": "6.0", + "frowning": "6.1", + "anguished": "6.1", + "fearful": "6.0", + "weary": "6.0", + "grimacing": "6.1", + "cold_sweat": "6.0", + "scream": "6.0", + "flushed": "6.0", + "dizzy_face": "6.0", + "rage": "6.0", + "angry": "6.0", + "innocent": "6.0", + "cowboy": "9.0", + "face_with_cowboy_hat": "9.0", + "clown": "9.0", + "clown_face": "9.0", + "lying_face": "9.0", + "liar": "9.0", + "mask": "6.0", + "thermometer_face": "8.0", + "face_with_thermometer": "8.0", + "head_bandage": "8.0", + "face_with_head_bandage": "8.0", + "nauseated_face": "9.0", + "sick": "9.0", + "sneezing_face": "9.0", + "sneeze": "9.0", + "smiling_imp": "6.0", + "imp": "6.0", + "japanese_ogre": "6.0", + "japanese_goblin": "6.0", + "skull": "6.0", + "skeleton": "6.0", + "skull_crossbones": "1.1", + "skull_and_crossbones": "1.1", + "ghost": "6.0", + "alien": "6.0", + "space_invader": "6.0", + "robot": "8.0", + "robot_face": "8.0", + "poop": "6.0", + "shit": "6.0", + "hankey": "6.0", + "poo": "6.0", + "smiley_cat": "6.0", + "smile_cat": "6.0", + "joy_cat": "6.0", + "heart_eyes_cat": "6.0", + "smirk_cat": "6.0", + "kissing_cat": "6.0", + "scream_cat": "6.0", + "crying_cat_face": "6.0", + "pouting_cat": "6.0", + "see_no_evil": "6.0", + "hear_no_evil": "6.0", + "speak_no_evil": "6.0", + "boy": "6.0", + "boy_tone1": "8.0", + "boy_tone2": "8.0", + "boy_tone3": "8.0", + "boy_tone4": "8.0", + "boy_tone5": "8.0", + "girl": "6.0", + "girl_tone1": "8.0", + "girl_tone2": "8.0", + "girl_tone3": "8.0", + "girl_tone4": "8.0", + "girl_tone5": "8.0", + "man": "6.0", + "man_tone1": "8.0", + "man_tone2": "8.0", + "man_tone3": "8.0", + "man_tone4": "8.0", + "man_tone5": "8.0", + "woman": "6.0", + "woman_tone1": "8.0", + "woman_tone2": "8.0", + "woman_tone3": "8.0", + "woman_tone4": "8.0", + "woman_tone5": "8.0", + "older_man": "6.0", + "older_man_tone1": "8.0", + "older_man_tone2": "8.0", + "older_man_tone3": "8.0", + "older_man_tone4": "8.0", + "older_man_tone5": "8.0", + "older_woman": "6.0", + "grandma": "6.0", + "older_woman_tone1": "8.0", + "grandma_tone1": "8.0", + "older_woman_tone2": "8.0", + "grandma_tone2": "8.0", + "older_woman_tone3": "8.0", + "grandma_tone3": "8.0", + "older_woman_tone4": "8.0", + "grandma_tone4": "8.0", + "older_woman_tone5": "8.0", + "grandma_tone5": "8.0", + "baby": "6.0", + "baby_tone1": "8.0", + "baby_tone2": "8.0", + "baby_tone3": "8.0", + "baby_tone4": "8.0", + "baby_tone5": "8.0", + "angel": "6.0", + "angel_tone1": "8.0", + "angel_tone2": "8.0", + "angel_tone3": "8.0", + "angel_tone4": "8.0", + "angel_tone5": "8.0", + "cop": "6.0", + "cop_tone1": "8.0", + "cop_tone2": "8.0", + "cop_tone3": "8.0", + "cop_tone4": "8.0", + "cop_tone5": "8.0", + "spy": "7.0", + "sleuth_or_spy": "7.0", + "spy_tone1": "8.0", + "sleuth_or_spy_tone1": "8.0", + "spy_tone2": "8.0", + "sleuth_or_spy_tone2": "8.0", + "spy_tone3": "8.0", + "sleuth_or_spy_tone3": "8.0", + "spy_tone4": "8.0", + "sleuth_or_spy_tone4": "8.0", + "spy_tone5": "8.0", + "sleuth_or_spy_tone5": "8.0", + "guardsman": "6.0", + "guardsman_tone1": "8.0", + "guardsman_tone2": "8.0", + "guardsman_tone3": "8.0", + "guardsman_tone4": "8.0", + "guardsman_tone5": "8.0", + "construction_worker": "6.0", + "construction_worker_tone1": "8.0", + "construction_worker_tone2": "8.0", + "construction_worker_tone3": "8.0", + "construction_worker_tone4": "8.0", + "construction_worker_tone5": "8.0", + "man_with_turban": "6.0", + "man_with_turban_tone1": "8.0", + "man_with_turban_tone2": "8.0", + "man_with_turban_tone3": "8.0", + "man_with_turban_tone4": "8.0", + "man_with_turban_tone5": "8.0", + "person_with_blond_hair": "6.0", + "person_with_blond_hair_tone1": "8.0", + "person_with_blond_hair_tone2": "8.0", + "person_with_blond_hair_tone3": "8.0", + "person_with_blond_hair_tone4": "8.0", + "person_with_blond_hair_tone5": "8.0", + "santa": "6.0", + "santa_tone1": "8.0", + "santa_tone2": "8.0", + "santa_tone3": "8.0", + "santa_tone4": "8.0", + "santa_tone5": "8.0", + "mrs_claus": "9.0", + "mother_christmas": "9.0", + "mrs_claus_tone1": "9.0", + "mother_christmas_tone1": "9.0", + "mrs_claus_tone2": "9.0", + "mother_christmas_tone2": "9.0", + "mrs_claus_tone3": "9.0", + "mother_christmas_tone3": "9.0", + "mrs_claus_tone4": "9.0", + "mother_christmas_tone4": "9.0", + "mrs_claus_tone5": "9.0", + "mother_christmas_tone5": "9.0", + "princess": "6.0", + "princess_tone1": "8.0", + "princess_tone2": "8.0", + "princess_tone3": "8.0", + "princess_tone4": "8.0", + "princess_tone5": "8.0", + "prince": "9.0", + "prince_tone1": "9.0", + "prince_tone2": "9.0", + "prince_tone3": "9.0", + "prince_tone4": "9.0", + "prince_tone5": "9.0", + "bride_with_veil": "6.0", + "bride_with_veil_tone1": "8.0", + "bride_with_veil_tone2": "8.0", + "bride_with_veil_tone3": "8.0", + "bride_with_veil_tone4": "8.0", + "bride_with_veil_tone5": "8.0", + "man_in_tuxedo": "9.0", + "man_in_tuxedo_tone1": "9.0", + "tuxedo_tone1": "9.0", + "man_in_tuxedo_tone2": "9.0", + "tuxedo_tone2": "9.0", + "man_in_tuxedo_tone3": "9.0", + "tuxedo_tone3": "9.0", + "man_in_tuxedo_tone4": "9.0", + "tuxedo_tone4": "9.0", + "man_in_tuxedo_tone5": "9.0", + "tuxedo_tone5": "9.0", + "pregnant_woman": "9.0", + "expecting_woman": "9.0", + "pregnant_woman_tone1": "9.0", + "expecting_woman_tone1": "9.0", + "pregnant_woman_tone2": "9.0", + "expecting_woman_tone2": "9.0", + "pregnant_woman_tone3": "9.0", + "expecting_woman_tone3": "9.0", + "pregnant_woman_tone4": "9.0", + "expecting_woman_tone4": "9.0", + "pregnant_woman_tone5": "9.0", + "expecting_woman_tone5": "9.0", + "man_with_gua_pi_mao": "6.0", + "man_with_gua_pi_mao_tone1": "8.0", + "man_with_gua_pi_mao_tone2": "8.0", + "man_with_gua_pi_mao_tone3": "8.0", + "man_with_gua_pi_mao_tone4": "8.0", + "man_with_gua_pi_mao_tone5": "8.0", + "person_frowning": "6.0", + "person_frowning_tone1": "8.0", + "person_frowning_tone2": "8.0", + "person_frowning_tone3": "8.0", + "person_frowning_tone4": "8.0", + "person_frowning_tone5": "8.0", + "person_with_pouting_face": "6.0", + "person_with_pouting_face_tone1": "8.0", + "person_with_pouting_face_tone2": "8.0", + "person_with_pouting_face_tone3": "8.0", + "person_with_pouting_face_tone4": "8.0", + "person_with_pouting_face_tone5": "8.0", + "no_good": "6.0", + "no_good_tone1": "8.0", + "no_good_tone2": "8.0", + "no_good_tone3": "8.0", + "no_good_tone4": "8.0", + "no_good_tone5": "8.0", + "ok_woman": "6.0", + "ok_woman_tone1": "8.0", + "ok_woman_tone2": "8.0", + "ok_woman_tone3": "8.0", + "ok_woman_tone4": "8.0", + "ok_woman_tone5": "8.0", + "information_desk_person": "6.0", + "information_desk_person_tone1": "8.0", + "information_desk_person_tone2": "8.0", + "information_desk_person_tone3": "8.0", + "information_desk_person_tone4": "8.0", + "information_desk_person_tone5": "8.0", + "raising_hand": "6.0", + "raising_hand_tone1": "8.0", + "raising_hand_tone2": "8.0", + "raising_hand_tone3": "8.0", + "raising_hand_tone4": "8.0", + "raising_hand_tone5": "8.0", + "bow": "6.0", + "bow_tone1": "8.0", + "bow_tone2": "8.0", + "bow_tone3": "8.0", + "bow_tone4": "8.0", + "bow_tone5": "8.0", + "face_palm": "9.0", + "facepalm": "9.0", + "face_palm_tone1": "9.0", + "facepalm_tone1": "9.0", + "face_palm_tone2": "9.0", + "facepalm_tone2": "9.0", + "face_palm_tone3": "9.0", + "facepalm_tone3": "9.0", + "face_palm_tone4": "9.0", + "facepalm_tone4": "9.0", + "face_palm_tone5": "9.0", + "facepalm_tone5": "9.0", + "shrug": "9.0", + "shrug_tone1": "9.0", + "shrug_tone2": "9.0", + "shrug_tone3": "9.0", + "shrug_tone4": "9.0", + "shrug_tone5": "9.0", + "massage": "6.0", + "massage_tone1": "8.0", + "massage_tone2": "8.0", + "massage_tone3": "8.0", + "massage_tone4": "8.0", + "massage_tone5": "8.0", + "haircut": "6.0", + "haircut_tone1": "8.0", + "haircut_tone2": "8.0", + "haircut_tone3": "8.0", + "haircut_tone4": "8.0", + "haircut_tone5": "8.0", + "walking": "6.0", + "walking_tone1": "8.0", + "walking_tone2": "8.0", + "walking_tone3": "8.0", + "walking_tone4": "8.0", + "walking_tone5": "8.0", + "runner": "6.0", + "runner_tone1": "8.0", + "runner_tone2": "8.0", + "runner_tone3": "8.0", + "runner_tone4": "8.0", + "runner_tone5": "8.0", + "dancer": "6.0", + "dancer_tone1": "8.0", + "dancer_tone2": "8.0", + "dancer_tone3": "8.0", + "dancer_tone4": "8.0", + "dancer_tone5": "8.0", + "man_dancing": "9.0", + "male_dancer": "9.0", + "man_dancing_tone1": "9.0", + "male_dancer_tone1": "9.0", + "man_dancing_tone2": "9.0", + "male_dancer_tone2": "9.0", + "man_dancing_tone3": "9.0", + "male_dancer_tone3": "9.0", + "man_dancing_tone4": "9.0", + "male_dancer_tone4": "9.0", + "man_dancing_tone5": "9.0", + "male_dancer_tone5": "9.0", + "dancers": "6.0", + "levitate": "7.0", + "man_in_business_suit_levitating": "7.0", + "speaking_head": "7.0", + "speaking_head_in_silhouette": "7.0", + "bust_in_silhouette": "6.0", + "busts_in_silhouette": "6.0", + "fencer": "9.0", + "fencing": "9.0", + "horse_racing": "6.0", + "horse_racing_tone1": "8.0", + "horse_racing_tone2": "8.0", + "horse_racing_tone3": "8.0", + "horse_racing_tone4": "8.0", + "horse_racing_tone5": "8.0", + "skier": "5.2", + "snowboarder": "6.0", + "golfer": "7.0", + "surfer": "6.0", + "surfer_tone1": "8.0", + "surfer_tone2": "8.0", + "surfer_tone3": "8.0", + "surfer_tone4": "8.0", + "surfer_tone5": "8.0", + "rowboat": "6.0", + "rowboat_tone1": "8.0", + "rowboat_tone2": "8.0", + "rowboat_tone3": "8.0", + "rowboat_tone4": "8.0", + "rowboat_tone5": "8.0", + "swimmer": "6.0", + "swimmer_tone1": "8.0", + "swimmer_tone2": "8.0", + "swimmer_tone3": "8.0", + "swimmer_tone4": "8.0", + "swimmer_tone5": "8.0", + "basketball_player": "5.2", + "person_with_ball": "5.2", + "basketball_player_tone1": "8.0", + "person_with_ball_tone1": "8.0", + "basketball_player_tone2": "8.0", + "person_with_ball_tone2": "8.0", + "basketball_player_tone3": "8.0", + "person_with_ball_tone3": "8.0", + "basketball_player_tone4": "8.0", + "person_with_ball_tone4": "8.0", + "basketball_player_tone5": "8.0", + "person_with_ball_tone5": "8.0", + "lifter": "7.0", + "weight_lifter": "7.0", + "lifter_tone1": "8.0", + "weight_lifter_tone1": "8.0", + "lifter_tone2": "8.0", + "weight_lifter_tone2": "8.0", + "lifter_tone3": "8.0", + "weight_lifter_tone3": "8.0", + "lifter_tone4": "8.0", + "weight_lifter_tone4": "8.0", + "lifter_tone5": "8.0", + "weight_lifter_tone5": "8.0", + "bicyclist": "6.0", + "bicyclist_tone1": "8.0", + "bicyclist_tone2": "8.0", + "bicyclist_tone3": "8.0", + "bicyclist_tone4": "8.0", + "bicyclist_tone5": "8.0", + "mountain_bicyclist": "6.0", + "mountain_bicyclist_tone1": "8.0", + "mountain_bicyclist_tone2": "8.0", + "mountain_bicyclist_tone3": "8.0", + "mountain_bicyclist_tone4": "8.0", + "mountain_bicyclist_tone5": "8.0", + "race_car": "7.0", + "racing_car": "7.0", + "motorcycle": "7.0", + "racing_motorcycle": "7.0", + "cartwheel": "9.0", + "person_doing_cartwheel": "9.0", + "cartwheel_tone1": "9.0", + "person_doing_cartwheel_tone1": "9.0", + "cartwheel_tone2": "9.0", + "person_doing_cartwheel_tone2": "9.0", + "cartwheel_tone3": "9.0", + "person_doing_cartwheel_tone3": "9.0", + "cartwheel_tone4": "9.0", + "person_doing_cartwheel_tone4": "9.0", + "cartwheel_tone5": "9.0", + "person_doing_cartwheel_tone5": "9.0", + "wrestlers": "9.0", + "wrestling": "9.0", + "wrestlers_tone1": "9.0", + "wrestling_tone1": "9.0", + "wrestlers_tone2": "9.0", + "wrestling_tone2": "9.0", + "wrestlers_tone3": "9.0", + "wrestling_tone3": "9.0", + "wrestlers_tone4": "9.0", + "wrestling_tone4": "9.0", + "wrestlers_tone5": "9.0", + "wrestling_tone5": "9.0", + "water_polo": "9.0", + "water_polo_tone1": "9.0", + "water_polo_tone2": "9.0", + "water_polo_tone3": "9.0", + "water_polo_tone4": "9.0", + "water_polo_tone5": "9.0", + "handball": "9.0", + "handball_tone1": "9.0", + "handball_tone2": "9.0", + "handball_tone3": "9.0", + "handball_tone4": "9.0", + "handball_tone5": "9.0", + "juggling": "9.0", + "juggler": "9.0", + "juggling_tone1": "9.0", + "juggler_tone1": "9.0", + "juggling_tone2": "9.0", + "juggler_tone2": "9.0", + "juggling_tone3": "9.0", + "juggler_tone3": "9.0", + "juggling_tone4": "9.0", + "juggler_tone4": "9.0", + "juggling_tone5": "9.0", + "juggler_tone5": "9.0", + "couple": "6.0", + "two_men_holding_hands": "6.0", + "two_women_holding_hands": "6.0", + "couplekiss": "6.0", + "kiss_mm": "6.0", + "couplekiss_mm": "6.0", + "kiss_ww": "6.0", + "couplekiss_ww": "6.0", + "couple_with_heart": "6.0", + "couple_mm": "6.0", + "couple_with_heart_mm": "6.0", + "couple_ww": "6.0", + "couple_with_heart_ww": "6.0", + "family": "6.0", + "family_mwg": "6.0", + "family_mwgb": "6.0", + "family_mwbb": "6.0", + "family_mwgg": "6.0", + "family_mmb": "6.0", + "family_mmg": "6.0", + "family_mmgb": "6.0", + "family_mmbb": "6.0", + "family_mmgg": "6.0", + "family_wwb": "6.0", + "family_wwg": "6.0", + "family_wwgb": "6.0", + "family_wwbb": "6.0", + "family_wwgg": "6.0", + "tone1": "8.0", + "tone2": "8.0", + "tone3": "8.0", + "tone4": "8.0", + "tone5": "8.0", + "muscle": "6.0", + "muscle_tone1": "8.0", + "muscle_tone2": "8.0", + "muscle_tone3": "8.0", + "muscle_tone4": "8.0", + "muscle_tone5": "8.0", + "selfie": "9.0", + "selfie_tone1": "9.0", + "selfie_tone2": "9.0", + "selfie_tone3": "9.0", + "selfie_tone4": "9.0", + "selfie_tone5": "9.0", + "point_left": "6.0", + "point_left_tone1": "8.0", + "point_left_tone2": "8.0", + "point_left_tone3": "8.0", + "point_left_tone4": "8.0", + "point_left_tone5": "8.0", + "point_right": "6.0", + "point_right_tone1": "8.0", + "point_right_tone2": "8.0", + "point_right_tone3": "8.0", + "point_right_tone4": "8.0", + "point_right_tone5": "8.0", + "point_up": "1.1", + "point_up_tone1": "8.0", + "point_up_tone2": "8.0", + "point_up_tone3": "8.0", + "point_up_tone4": "8.0", + "point_up_tone5": "8.0", + "point_up_2": "6.0", + "point_up_2_tone1": "8.0", + "point_up_2_tone2": "8.0", + "point_up_2_tone3": "8.0", + "point_up_2_tone4": "8.0", + "point_up_2_tone5": "8.0", + "middle_finger": "7.0", + "reversed_hand_with_middle_finger_extended": "7.0", + "middle_finger_tone1": "8.0", + "reversed_hand_with_middle_finger_extended_tone1": "8.0", + "middle_finger_tone2": "8.0", + "reversed_hand_with_middle_finger_extended_tone2": "8.0", + "middle_finger_tone3": "8.0", + "reversed_hand_with_middle_finger_extended_tone3": "8.0", + "middle_finger_tone4": "8.0", + "reversed_hand_with_middle_finger_extended_tone4": "8.0", + "middle_finger_tone5": "8.0", + "reversed_hand_with_middle_finger_extended_tone5": "8.0", + "point_down": "6.0", + "point_down_tone1": "8.0", + "point_down_tone2": "8.0", + "point_down_tone3": "8.0", + "point_down_tone4": "8.0", + "point_down_tone5": "8.0", + "v": "1.1", + "v_tone1": "8.0", + "v_tone2": "8.0", + "v_tone3": "8.0", + "v_tone4": "8.0", + "v_tone5": "8.0", + "fingers_crossed": "9.0", + "hand_with_index_and_middle_finger_crossed": "9.0", + "fingers_crossed_tone1": "9.0", + "hand_with_index_and_middle_fingers_crossed_tone1": "9.0", + "fingers_crossed_tone2": "9.0", + "hand_with_index_and_middle_fingers_crossed_tone2": "9.0", + "fingers_crossed_tone3": "9.0", + "hand_with_index_and_middle_fingers_crossed_tone3": "9.0", + "fingers_crossed_tone4": "9.0", + "hand_with_index_and_middle_fingers_crossed_tone4": "9.0", + "fingers_crossed_tone5": "9.0", + "hand_with_index_and_middle_fingers_crossed_tone5": "9.0", + "vulcan": "7.0", + "raised_hand_with_part_between_middle_and_ring_fingers": "7.0", + "vulcan_tone1": "8.0", + "raised_hand_with_part_between_middle_and_ring_fingers_tone1": "8.0", + "vulcan_tone2": "8.0", + "raised_hand_with_part_between_middle_and_ring_fingers_tone2": "8.0", + "vulcan_tone3": "8.0", + "raised_hand_with_part_between_middle_and_ring_fingers_tone3": "8.0", + "vulcan_tone4": "8.0", + "raised_hand_with_part_between_middle_and_ring_fingers_tone4": "8.0", + "vulcan_tone5": "8.0", + "raised_hand_with_part_between_middle_and_ring_fingers_tone5": "8.0", + "metal": "8.0", + "sign_of_the_horns": "8.0", + "metal_tone1": "8.0", + "sign_of_the_horns_tone1": "8.0", + "metal_tone2": "8.0", + "sign_of_the_horns_tone2": "8.0", + "metal_tone3": "8.0", + "sign_of_the_horns_tone3": "8.0", + "metal_tone4": "8.0", + "sign_of_the_horns_tone4": "8.0", + "metal_tone5": "8.0", + "sign_of_the_horns_tone5": "8.0", + "call_me": "9.0", + "call_me_hand": "9.0", + "call_me_tone1": "9.0", + "call_me_hand_tone1": "9.0", + "call_me_tone2": "9.0", + "call_me_hand_tone2": "9.0", + "call_me_tone3": "9.0", + "call_me_hand_tone3": "9.0", + "call_me_tone4": "9.0", + "call_me_hand_tone4": "9.0", + "call_me_tone5": "9.0", + "call_me_hand_tone5": "9.0", + "hand_splayed": "7.0", + "raised_hand_with_fingers_splayed": "7.0", + "hand_splayed_tone1": "8.0", + "raised_hand_with_fingers_splayed_tone1": "8.0", + "hand_splayed_tone2": "8.0", + "raised_hand_with_fingers_splayed_tone2": "8.0", + "hand_splayed_tone3": "8.0", + "raised_hand_with_fingers_splayed_tone3": "8.0", + "hand_splayed_tone4": "8.0", + "raised_hand_with_fingers_splayed_tone4": "8.0", + "hand_splayed_tone5": "8.0", + "raised_hand_with_fingers_splayed_tone5": "8.0", + "raised_hand": "6.0", + "raised_hand_tone1": "8.0", + "raised_hand_tone2": "8.0", + "raised_hand_tone3": "8.0", + "raised_hand_tone4": "8.0", + "raised_hand_tone5": "8.0", + "ok_hand": "6.0", + "ok_hand_tone1": "8.0", + "ok_hand_tone2": "8.0", + "ok_hand_tone3": "8.0", + "ok_hand_tone4": "8.0", + "ok_hand_tone5": "8.0", + "thumbsup": "6.0", + "+1": "6.0", + "thumbup": "6.0", + "thumbsup_tone1": "8.0", + "+1_tone1": "8.0", + "thumbup_tone1": "8.0", + "thumbsup_tone2": "8.0", + "+1_tone2": "8.0", + "thumbup_tone2": "8.0", + "thumbsup_tone3": "8.0", + "+1_tone3": "8.0", + "thumbup_tone3": "8.0", + "thumbsup_tone4": "8.0", + "+1_tone4": "8.0", + "thumbup_tone4": "8.0", + "thumbsup_tone5": "8.0", + "+1_tone5": "8.0", + "thumbup_tone5": "8.0", + "thumbsdown": "6.0", + "-1": "6.0", + "thumbdown": "6.0", + "thumbsdown_tone1": "8.0", + "-1_tone1": "8.0", + "thumbdown_tone1": "8.0", + "thumbsdown_tone2": "8.0", + "-1_tone2": "8.0", + "thumbdown_tone2": "8.0", + "thumbsdown_tone3": "8.0", + "-1_tone3": "8.0", + "thumbdown_tone3": "8.0", + "thumbsdown_tone4": "8.0", + "-1_tone4": "8.0", + "thumbdown_tone4": "8.0", + "thumbsdown_tone5": "8.0", + "-1_tone5": "8.0", + "thumbdown_tone5": "8.0", + "fist": "6.0", + "fist_tone1": "8.0", + "fist_tone2": "8.0", + "fist_tone3": "8.0", + "fist_tone4": "8.0", + "fist_tone5": "8.0", + "punch": "6.0", + "punch_tone1": "8.0", + "punch_tone2": "8.0", + "punch_tone3": "8.0", + "punch_tone4": "8.0", + "punch_tone5": "8.0", + "left_facing_fist": "9.0", + "left_fist": "9.0", + "left_facing_fist_tone1": "9.0", + "left_fist_tone1": "9.0", + "left_facing_fist_tone2": "9.0", + "left_fist_tone2": "9.0", + "left_facing_fist_tone3": "9.0", + "left_fist_tone3": "9.0", + "left_facing_fist_tone4": "9.0", + "left_fist_tone4": "9.0", + "left_facing_fist_tone5": "9.0", + "left_fist_tone5": "9.0", + "right_facing_fist": "9.0", + "right_fist": "9.0", + "right_facing_fist_tone1": "9.0", + "right_fist_tone1": "9.0", + "right_facing_fist_tone2": "9.0", + "right_fist_tone2": "9.0", + "right_facing_fist_tone3": "9.0", + "right_fist_tone3": "9.0", + "right_facing_fist_tone4": "9.0", + "right_fist_tone4": "9.0", + "right_facing_fist_tone5": "9.0", + "right_fist_tone5": "9.0", + "raised_back_of_hand": "9.0", + "back_of_hand": "9.0", + "raised_back_of_hand_tone1": "9.0", + "back_of_hand_tone1": "9.0", + "raised_back_of_hand_tone2": "9.0", + "back_of_hand_tone2": "9.0", + "raised_back_of_hand_tone3": "9.0", + "back_of_hand_tone3": "9.0", + "raised_back_of_hand_tone4": "9.0", + "back_of_hand_tone4": "9.0", + "raised_back_of_hand_tone5": "9.0", + "back_of_hand_tone5": "9.0", + "wave": "6.0", + "wave_tone1": "8.0", + "wave_tone2": "8.0", + "wave_tone3": "8.0", + "wave_tone4": "8.0", + "wave_tone5": "8.0", + "clap": "6.0", + "clap_tone1": "8.0", + "clap_tone2": "8.0", + "clap_tone3": "8.0", + "clap_tone4": "8.0", + "clap_tone5": "8.0", + "writing_hand": "1.1", + "writing_hand_tone1": "8.0", + "writing_hand_tone2": "8.0", + "writing_hand_tone3": "8.0", + "writing_hand_tone4": "8.0", + "writing_hand_tone5": "8.0", + "open_hands": "6.0", + "open_hands_tone1": "8.0", + "open_hands_tone2": "8.0", + "open_hands_tone3": "8.0", + "open_hands_tone4": "8.0", + "open_hands_tone5": "8.0", + "raised_hands": "6.0", + "raised_hands_tone1": "8.0", + "raised_hands_tone2": "8.0", + "raised_hands_tone3": "8.0", + "raised_hands_tone4": "8.0", + "raised_hands_tone5": "8.0", + "pray": "6.0", + "pray_tone1": "8.0", + "pray_tone2": "8.0", + "pray_tone3": "8.0", + "pray_tone4": "8.0", + "pray_tone5": "8.0", + "handshake": "9.0", + "shaking_hands": "9.0", + "handshake_tone1": "9.0", + "shaking_hands_tone1": "9.0", + "handshake_tone2": "9.0", + "shaking_hands_tone2": "9.0", + "handshake_tone3": "9.0", + "shaking_hands_tone3": "9.0", + "handshake_tone4": "9.0", + "shaking_hands_tone4": "9.0", + "handshake_tone5": "9.0", + "shaking_hands_tone5": "9.0", + "nail_care": "6.0", + "nail_care_tone1": "8.0", + "nail_care_tone2": "8.0", + "nail_care_tone3": "8.0", + "nail_care_tone4": "8.0", + "nail_care_tone5": "8.0", + "ear": "6.0", + "ear_tone1": "8.0", + "ear_tone2": "8.0", + "ear_tone3": "8.0", + "ear_tone4": "8.0", + "ear_tone5": "8.0", + "nose": "6.0", + "nose_tone1": "8.0", + "nose_tone2": "8.0", + "nose_tone3": "8.0", + "nose_tone4": "8.0", + "nose_tone5": "8.0", + "footprints": "6.0", + "eyes": "6.0", + "eye": "7.0", + "eye_in_speech_bubble": "7.0", + "tongue": "6.0", + "lips": "6.0", + "kiss": "6.0", + "cupid": "6.0", + "heart": "1.1", + "heartbeat": "6.0", + "broken_heart": "6.0", + "two_hearts": "6.0", + "sparkling_heart": "6.0", + "heartpulse": "6.0", + "blue_heart": "6.0", + "green_heart": "6.0", + "yellow_heart": "6.0", + "purple_heart": "6.0", + "black_heart": "9.0", + "gift_heart": "6.0", + "revolving_hearts": "6.0", + "heart_decoration": "6.0", + "heart_exclamation": "1.1", + "heavy_heart_exclamation_mark_ornament": "1.1", + "love_letter": "6.0", + "zzz": "6.0", + "anger": "6.0", + "bomb": "6.0", + "boom": "6.0", + "sweat_drops": "6.0", + "dash": "6.0", + "dizzy": "6.0", + "speech_balloon": "6.0", + "speech_left": "7.0", + "left_speech_bubble": "7.0", + "anger_right": "7.0", + "right_anger_bubble": "7.0", + "thought_balloon": "6.0", + "hole": "7.0", + "eyeglasses": "6.0", + "dark_sunglasses": "7.0", + "necktie": "6.0", + "shirt": "6.0", + "jeans": "6.0", + "dress": "6.0", + "kimono": "6.0", + "bikini": "6.0", + "womans_clothes": "6.0", + "purse": "6.0", + "handbag": "6.0", + "pouch": "6.0", + "shopping_bags": "7.0", + "school_satchel": "6.0", + "mans_shoe": "6.0", + "athletic_shoe": "6.0", + "high_heel": "6.0", + "sandal": "6.0", + "boot": "6.0", + "crown": "6.0", + "womans_hat": "6.0", + "tophat": "6.0", + "mortar_board": "6.0", + "helmet_with_cross": "5.2", + "helmet_with_white_cross": "5.2", + "prayer_beads": "8.0", + "lipstick": "6.0", + "ring": "6.0", + "gem": "6.0", + "monkey_face": "6.0", + "monkey": "6.0", + "gorilla": "9.0", + "dog": "6.0", + "dog2": "6.0", + "poodle": "6.0", + "wolf": "6.0", + "fox": "9.0", + "fox_face": "9.0", + "cat": "6.0", + "cat2": "6.0", + "lion_face": "8.0", + "lion": "8.0", + "tiger": "6.0", + "tiger2": "6.0", + "leopard": "6.0", + "horse": "6.0", + "racehorse": "6.0", + "deer": "9.0", + "unicorn": "8.0", + "unicorn_face": "8.0", + "cow": "6.0", + "ox": "6.0", + "water_buffalo": "6.0", + "cow2": "6.0", + "pig": "6.0", + "pig2": "6.0", + "boar": "6.0", + "pig_nose": "6.0", + "ram": "6.0", + "sheep": "6.0", + "goat": "6.0", + "dromedary_camel": "6.0", + "camel": "6.0", + "elephant": "6.0", + "rhino": "9.0", + "rhinoceros": "9.0", + "mouse": "6.0", + "mouse2": "6.0", + "rat": "6.0", + "hamster": "6.0", + "rabbit": "6.0", + "rabbit2": "6.0", + "chipmunk": "7.0", + "bat": "9.0", + "bear": "6.0", + "koala": "6.0", + "panda_face": "6.0", + "feet": "6.0", + "paw_prints": "6.0", + "turkey": "8.0", + "chicken": "6.0", + "rooster": "6.0", + "hatching_chick": "6.0", + "baby_chick": "6.0", + "hatched_chick": "6.0", + "bird": "6.0", + "penguin": "6.0", + "dove": "7.0", + "dove_of_peace": "7.0", + "eagle": "9.0", + "duck": "9.0", + "owl": "9.0", + "frog": "6.0", + "crocodile": "6.0", + "turtle": "6.0", + "lizard": "9.0", + "snake": "6.0", + "dragon_face": "6.0", + "dragon": "6.0", + "whale": "6.0", + "whale2": "6.0", + "dolphin": "6.0", + "fish": "6.0", + "tropical_fish": "6.0", + "blowfish": "6.0", + "shark": "9.0", + "octopus": "6.0", + "shell": "6.0", + "crab": "8.0", + "shrimp": "9.0", + "squid": "9.0", + "butterfly": "9.0", + "snail": "6.0", + "bug": "6.0", + "ant": "6.0", + "bee": "6.0", + "beetle": "6.0", + "spider": "7.0", + "spider_web": "7.0", + "scorpion": "8.0", + "bouquet": "6.0", + "cherry_blossom": "6.0", + "white_flower": "6.0", + "rosette": "7.0", + "rose": "6.0", + "wilted_rose": "9.0", + "wilted_flower": "9.0", + "hibiscus": "6.0", + "sunflower": "6.0", + "blossom": "6.0", + "tulip": "6.0", + "seedling": "6.0", + "evergreen_tree": "6.0", + "deciduous_tree": "6.0", + "palm_tree": "6.0", + "cactus": "6.0", + "ear_of_rice": "6.0", + "herb": "6.0", + "shamrock": "4.1", + "four_leaf_clover": "6.0", + "maple_leaf": "6.0", + "fallen_leaf": "6.0", + "leaves": "6.0", + "grapes": "6.0", + "melon": "6.0", + "watermelon": "6.0", + "tangerine": "6.0", + "lemon": "6.0", + "banana": "6.0", + "pineapple": "6.0", + "apple": "6.0", + "green_apple": "6.0", + "pear": "6.0", + "peach": "6.0", + "cherries": "6.0", + "strawberry": "6.0", + "kiwi": "9.0", + "kiwifruit": "9.0", + "tomato": "6.0", + "avocado": "9.0", + "eggplant": "6.0", + "potato": "9.0", + "carrot": "9.0", + "corn": "6.0", + "hot_pepper": "7.0", + "cucumber": "9.0", + "mushroom": "6.0", + "peanuts": "9.0", + "shelled_peanut": "9.0", + "chestnut": "6.0", + "bread": "6.0", + "croissant": "9.0", + "french_bread": "9.0", + "baguette_bread": "9.0", + "pancakes": "9.0", + "cheese": "8.0", + "cheese_wedge": "8.0", + "meat_on_bone": "6.0", + "poultry_leg": "6.0", + "bacon": "9.0", + "hamburger": "6.0", + "fries": "6.0", + "pizza": "6.0", + "hotdog": "8.0", + "hot_dog": "8.0", + "taco": "8.0", + "burrito": "8.0", + "stuffed_flatbread": "9.0", + "stuffed_pita": "9.0", + "egg": "9.0", + "cooking": "6.0", + "shallow_pan_of_food": "9.0", + "paella": "9.0", + "stew": "6.0", + "salad": "9.0", + "green_salad": "9.0", + "popcorn": "8.0", + "bento": "6.0", + "rice_cracker": "6.0", + "rice_ball": "6.0", + "rice": "6.0", + "curry": "6.0", + "ramen": "6.0", + "spaghetti": "6.0", + "sweet_potato": "6.0", + "oden": "6.0", + "sushi": "6.0", + "fried_shrimp": "6.0", + "fish_cake": "6.0", + "dango": "6.0", + "icecream": "6.0", + "shaved_ice": "6.0", + "ice_cream": "6.0", + "doughnut": "6.0", + "cookie": "6.0", + "birthday": "6.0", + "cake": "6.0", + "chocolate_bar": "6.0", + "candy": "6.0", + "lollipop": "6.0", + "custard": "6.0", + "pudding": "6.0", + "flan": "6.0", + "honey_pot": "6.0", + "baby_bottle": "6.0", + "milk": "9.0", + "glass_of_milk": "9.0", + "coffee": "4.0", + "tea": "6.0", + "sake": "6.0", + "champagne": "8.0", + "bottle_with_popping_cork": "8.0", + "wine_glass": "6.0", + "cocktail": "6.0", + "tropical_drink": "6.0", + "beer": "6.0", + "beers": "6.0", + "champagne_glass": "9.0", + "clinking_glass": "9.0", + "tumbler_glass": "9.0", + "whisky": "9.0", + "fork_knife_plate": "7.0", + "fork_and_knife_with_plate": "7.0", + "fork_and_knife": "6.0", + "spoon": "9.0", + "knife": "6.0", + "amphora": "8.0", + "earth_africa": "6.0", + "earth_americas": "6.0", + "earth_asia": "6.0", + "globe_with_meridians": "6.0", + "map": "7.0", + "world_map": "7.0", + "japan": "6.0", + "mountain_snow": "7.0", + "snow_capped_mountain": "7.0", + "mountain": "5.2", + "volcano": "6.0", + "mount_fuji": "6.0", + "camping": "7.0", + "beach": "7.0", + "beach_with_umbrella": "7.0", + "desert": "7.0", + "island": "7.0", + "desert_island": "7.0", + "park": "7.0", + "national_park": "7.0", + "stadium": "7.0", + "classical_building": "7.0", + "construction_site": "7.0", + "building_construction": "7.0", + "homes": "7.0", + "house_buildings": "7.0", + "cityscape": "7.0", + "house_abandoned": "7.0", + "derelict_house_building": "7.0", + "house": "6.0", + "house_with_garden": "6.0", + "office": "6.0", + "post_office": "6.0", + "european_post_office": "6.0", + "hospital": "6.0", + "bank": "6.0", + "hotel": "6.0", + "love_hotel": "6.0", + "convenience_store": "6.0", + "school": "6.0", + "department_store": "6.0", + "factory": "6.0", + "japanese_castle": "6.0", + "european_castle": "6.0", + "wedding": "6.0", + "tokyo_tower": "6.0", + "statue_of_liberty": "6.0", + "church": "5.2", + "mosque": "8.0", + "synagogue": "8.0", + "shinto_shrine": "5.2", + "kaaba": "8.0", + "fountain": "5.2", + "tent": "5.2", + "foggy": "6.0", + "night_with_stars": "6.0", + "sunrise_over_mountains": "6.0", + "sunrise": "6.0", + "city_dusk": "6.0", + "city_sunset": "6.0", + "city_sunrise": "6.0", + "bridge_at_night": "6.0", + "hotsprings": "1.1", + "milky_way": "6.0", + "carousel_horse": "6.0", + "ferris_wheel": "6.0", + "roller_coaster": "6.0", + "barber": "6.0", + "circus_tent": "6.0", + "performing_arts": "6.0", + "frame_photo": "7.0", + "frame_with_picture": "7.0", + "art": "6.0", + "slot_machine": "6.0", + "steam_locomotive": "6.0", + "railway_car": "6.0", + "bullettrain_side": "6.0", + "bullettrain_front": "6.0", + "train2": "6.0", + "metro": "6.0", + "light_rail": "6.0", + "station": "6.0", + "tram": "6.0", + "monorail": "6.0", + "mountain_railway": "6.0", + "train": "6.0", + "bus": "6.0", + "oncoming_bus": "6.0", + "trolleybus": "6.0", + "minibus": "6.0", + "ambulance": "6.0", + "fire_engine": "6.0", + "police_car": "6.0", + "oncoming_police_car": "6.0", + "taxi": "6.0", + "oncoming_taxi": "6.0", + "red_car": "6.0", + "oncoming_automobile": "6.0", + "blue_car": "6.0", + "truck": "6.0", + "articulated_lorry": "6.0", + "tractor": "6.0", + "bike": "6.0", + "scooter": "9.0", + "motor_scooter": "9.0", + "motorbike": "9.0", + "busstop": "6.0", + "motorway": "7.0", + "railway_track": "7.0", + "railroad_track": "7.0", + "fuelpump": "5.2", + "rotating_light": "6.0", + "traffic_light": "6.0", + "vertical_traffic_light": "6.0", + "construction": "6.0", + "octagonal_sign": "9.0", + "stop_sign": "9.0", + "anchor": "4.1", + "sailboat": "5.2", + "canoe": "9.0", + "kayak": "9.0", + "speedboat": "6.0", + "cruise_ship": "7.0", + "passenger_ship": "7.0", + "ferry": "5.2", + "motorboat": "7.0", + "ship": "6.0", + "airplane": "1.1", + "airplane_small": "7.0", + "small_airplane": "7.0", + "airplane_departure": "7.0", + "airplane_arriving": "7.0", + "seat": "6.0", + "helicopter": "6.0", + "suspension_railway": "6.0", + "mountain_cableway": "6.0", + "aerial_tramway": "6.0", + "rocket": "6.0", + "satellite_orbital": "7.0", + "bellhop": "7.0", + "bellhop_bell": "7.0", + "door": "6.0", + "sleeping_accommodation": "7.0", + "bed": "7.0", + "couch": "7.0", + "couch_and_lamp": "7.0", + "toilet": "6.0", + "shower": "6.0", + "bath": "6.0", + "bath_tone1": "8.0", + "bath_tone2": "8.0", + "bath_tone3": "8.0", + "bath_tone4": "8.0", + "bath_tone5": "8.0", + "bathtub": "6.0", + "hourglass": "1.1", + "hourglass_flowing_sand": "6.0", + "watch": "1.1", + "alarm_clock": "6.0", + "stopwatch": "6.0", + "timer": "6.0", + "timer_clock": "6.0", + "clock": "7.0", + "mantlepiece_clock": "7.0", + "clock12": "6.0", + "clock1230": "6.0", + "clock1": "6.0", + "clock130": "6.0", + "clock2": "6.0", + "clock230": "6.0", + "clock3": "6.0", + "clock330": "6.0", + "clock4": "6.0", + "clock430": "6.0", + "clock5": "6.0", + "clock530": "6.0", + "clock6": "6.0", + "clock630": "6.0", + "clock7": "6.0", + "clock730": "6.0", + "clock8": "6.0", + "clock830": "6.0", + "clock9": "6.0", + "clock930": "6.0", + "clock10": "6.0", + "clock1030": "6.0", + "clock11": "6.0", + "clock1130": "6.0", + "new_moon": "6.0", + "waxing_crescent_moon": "6.0", + "first_quarter_moon": "6.0", + "waxing_gibbous_moon": "6.0", + "full_moon": "6.0", + "waning_gibbous_moon": "6.0", + "last_quarter_moon": "6.0", + "waning_crescent_moon": "6.0", + "crescent_moon": "6.0", + "new_moon_with_face": "6.0", + "first_quarter_moon_with_face": "6.0", + "last_quarter_moon_with_face": "6.0", + "thermometer": "7.0", + "sunny": "1.1", + "full_moon_with_face": "6.0", + "sun_with_face": "6.0", + "star": "5.1", + "star2": "6.0", + "stars": "6.0", + "cloud": "1.1", + "partly_sunny": "5.2", + "thunder_cloud_rain": "5.2", + "thunder_cloud_and_rain": "5.2", + "white_sun_small_cloud": "7.0", + "white_sun_with_small_cloud": "7.0", + "white_sun_cloud": "7.0", + "white_sun_behind_cloud": "7.0", + "white_sun_rain_cloud": "7.0", + "white_sun_behind_cloud_with_rain": "7.0", + "cloud_rain": "7.0", + "cloud_with_rain": "7.0", + "cloud_snow": "7.0", + "cloud_with_snow": "7.0", + "cloud_lightning": "7.0", + "cloud_with_lightning": "7.0", + "cloud_tornado": "7.0", + "cloud_with_tornado": "7.0", + "fog": "7.0", + "wind_blowing_face": "7.0", + "cyclone": "6.0", + "rainbow": "6.0", + "closed_umbrella": "6.0", + "umbrella2": "1.1", + "umbrella": "4.0", + "beach_umbrella": "5.2", + "umbrella_on_ground": "5.2", + "zap": "4.0", + "snowflake": "1.1", + "snowman2": "1.1", + "snowman": "5.2", + "comet": "1.1", + "fire": "6.0", + "flame": "6.0", + "droplet": "6.0", + "ocean": "6.0", + "jack_o_lantern": "6.0", + "christmas_tree": "6.0", + "fireworks": "6.0", + "sparkler": "6.0", + "sparkles": "6.0", + "balloon": "6.0", + "tada": "6.0", + "confetti_ball": "6.0", + "tanabata_tree": "6.0", + "bamboo": "6.0", + "dolls": "6.0", + "flags": "6.0", + "wind_chime": "6.0", + "rice_scene": "6.0", + "ribbon": "6.0", + "gift": "6.0", + "reminder_ribbon": "7.0", + "tickets": "7.0", + "admission_tickets": "7.0", + "ticket": "6.0", + "military_medal": "7.0", + "trophy": "6.0", + "medal": "7.0", + "sports_medal": "7.0", + "first_place": "9.0", + "first_place_medal": "9.0", + "second_place": "9.0", + "second_place_medal": "9.0", + "third_place": "9.0", + "third_place_medal": "9.0", + "soccer": "5.2", + "baseball": "5.2", + "basketball": "6.0", + "volleyball": "8.0", + "football": "6.0", + "rugby_football": "6.0", + "tennis": "6.0", + "8ball": "6.0", + "bowling": "6.0", + "cricket": "8.0", + "cricket_bat_ball": "8.0", + "field_hockey": "8.0", + "hockey": "8.0", + "ping_pong": "8.0", + "table_tennis": "8.0", + "badminton": "8.0", + "boxing_glove": "9.0", + "boxing_gloves": "9.0", + "martial_arts_uniform": "9.0", + "karate_uniform": "9.0", + "goal": "9.0", + "goal_net": "9.0", + "dart": "6.0", + "golf": "5.2", + "ice_skate": "5.2", + "fishing_pole_and_fish": "6.0", + "running_shirt_with_sash": "6.0", + "ski": "6.0", + "video_game": "6.0", + "joystick": "7.0", + "game_die": "6.0", + "spades": "1.1", + "hearts": "1.1", + "diamonds": "1.1", + "clubs": "1.1", + "black_joker": "6.0", + "mahjong": "5.1", + "flower_playing_cards": "6.0", + "mute": "6.0", + "speaker": "6.0", + "sound": "6.0", + "loud_sound": "6.0", + "loudspeaker": "6.0", + "mega": "6.0", + "postal_horn": "6.0", + "bell": "6.0", + "no_bell": "6.0", + "musical_score": "6.0", + "musical_note": "6.0", + "notes": "6.0", + "microphone2": "7.0", + "studio_microphone": "7.0", + "level_slider": "7.0", + "control_knobs": "7.0", + "microphone": "6.0", + "headphones": "6.0", + "radio": "6.0", + "saxophone": "6.0", + "guitar": "6.0", + "musical_keyboard": "6.0", + "trumpet": "6.0", + "violin": "6.0", + "drum": "9.0", + "drum_with_drumsticks": "9.0", + "iphone": "6.0", + "calling": "6.0", + "telephone": "1.1", + "telephone_receiver": "6.0", + "pager": "6.0", + "fax": "6.0", + "battery": "6.0", + "electric_plug": "6.0", + "computer": "6.0", + "desktop": "7.0", + "desktop_computer": "7.0", + "printer": "7.0", + "keyboard": "1.1", + "mouse_three_button": "7.0", + "three_button_mouse": "7.0", + "trackball": "7.0", + "minidisc": "6.0", + "floppy_disk": "6.0", + "cd": "6.0", + "dvd": "6.0", + "movie_camera": "6.0", + "film_frames": "7.0", + "projector": "7.0", + "film_projector": "7.0", + "clapper": "6.0", + "tv": "6.0", + "camera": "6.0", + "camera_with_flash": "7.0", + "video_camera": "6.0", + "vhs": "6.0", + "mag": "6.0", + "mag_right": "6.0", + "microscope": "6.0", + "telescope": "6.0", + "satellite": "6.0", + "candle": "7.0", + "bulb": "6.0", + "flashlight": "6.0", + "izakaya_lantern": "6.0", + "notebook_with_decorative_cover": "6.0", + "closed_book": "6.0", + "book": "6.0", + "green_book": "6.0", + "blue_book": "6.0", + "orange_book": "6.0", + "books": "6.0", + "notebook": "6.0", + "ledger": "6.0", + "page_with_curl": "6.0", + "scroll": "6.0", + "page_facing_up": "6.0", + "newspaper": "6.0", + "newspaper2": "7.0", + "rolled_up_newspaper": "7.0", + "bookmark_tabs": "6.0", + "bookmark": "6.0", + "label": "7.0", + "moneybag": "6.0", + "yen": "6.0", + "dollar": "6.0", + "euro": "6.0", + "pound": "6.0", + "money_with_wings": "6.0", + "credit_card": "6.0", + "chart": "6.0", + "currency_exchange": "6.0", + "heavy_dollar_sign": "6.0", + "envelope": "1.1", + "e-mail": "6.0", + "email": "6.0", + "incoming_envelope": "6.0", + "envelope_with_arrow": "6.0", + "outbox_tray": "6.0", + "inbox_tray": "6.0", + "package": "6.0", + "mailbox": "6.0", + "mailbox_closed": "6.0", + "mailbox_with_mail": "6.0", + "mailbox_with_no_mail": "6.0", + "postbox": "6.0", + "ballot_box": "7.0", + "ballot_box_with_ballot": "7.0", + "pencil2": "1.1", + "black_nib": "1.1", + "pen_fountain": "7.0", + "lower_left_fountain_pen": "7.0", + "pen_ballpoint": "7.0", + "lower_left_ballpoint_pen": "7.0", + "paintbrush": "7.0", + "lower_left_paintbrush": "7.0", + "crayon": "7.0", + "lower_left_crayon": "7.0", + "pencil": "6.0", + "briefcase": "6.0", + "file_folder": "6.0", + "open_file_folder": "6.0", + "dividers": "7.0", + "card_index_dividers": "7.0", + "date": "6.0", + "calendar": "6.0", + "notepad_spiral": "7.0", + "spiral_note_pad": "7.0", + "calendar_spiral": "7.0", + "spiral_calendar_pad": "7.0", + "card_index": "6.0", + "chart_with_upwards_trend": "6.0", + "chart_with_downwards_trend": "6.0", + "bar_chart": "6.0", + "clipboard": "6.0", + "pushpin": "6.0", + "round_pushpin": "6.0", + "paperclip": "6.0", + "paperclips": "7.0", + "linked_paperclips": "7.0", + "straight_ruler": "6.0", + "triangular_ruler": "6.0", + "scissors": "1.1", + "card_box": "7.0", + "card_file_box": "7.0", + "file_cabinet": "7.0", + "wastebasket": "7.0", + "lock": "6.0", + "unlock": "6.0", + "lock_with_ink_pen": "6.0", + "closed_lock_with_key": "6.0", + "key": "6.0", + "key2": "7.0", + "old_key": "7.0", + "hammer": "6.0", + "pick": "5.2", + "hammer_pick": "4.1", + "hammer_and_pick": "4.1", + "tools": "7.0", + "hammer_and_wrench": "7.0", + "dagger": "7.0", + "dagger_knife": "7.0", + "crossed_swords": "4.1", + "gun": "6.0", + "bow_and_arrow": "8.0", + "archery": "8.0", + "shield": "7.0", + "wrench": "6.0", + "nut_and_bolt": "6.0", + "gear": "4.1", + "compression": "7.0", + "alembic": "4.1", + "scales": "4.1", + "link": "6.0", + "chains": "5.2", + "syringe": "6.0", + "pill": "6.0", + "smoking": "6.0", + "coffin": "4.1", + "urn": "4.1", + "funeral_urn": "4.1", + "moyai": "6.0", + "oil": "7.0", + "oil_drum": "7.0", + "crystal_ball": "6.0", + "shopping_cart": "9.0", + "shopping_trolley": "9.0", + "atm": "6.0", + "put_litter_in_its_place": "6.0", + "potable_water": "6.0", + "wheelchair": "4.1", + "mens": "6.0", + "womens": "6.0", + "restroom": "6.0", + "baby_symbol": "6.0", + "wc": "6.0", + "passport_control": "6.0", + "customs": "6.0", + "baggage_claim": "6.0", + "left_luggage": "6.0", + "warning": "4.0", + "children_crossing": "6.0", + "no_entry": "5.2", + "no_entry_sign": "6.0", + "no_bicycles": "6.0", + "no_smoking": "6.0", + "do_not_litter": "6.0", + "non-potable_water": "6.0", + "no_pedestrians": "6.0", + "no_mobile_phones": "6.0", + "underage": "6.0", + "radioactive": "1.1", + "radioactive_sign": "1.1", + "biohazard": "1.1", + "biohazard_sign": "1.1", + "arrow_up": "4.0", + "arrow_upper_right": "1.1", + "arrow_right": "1.1", + "arrow_lower_right": "1.1", + "arrow_down": "4.0", + "arrow_lower_left": "1.1", + "arrow_left": "4.0", + "arrow_upper_left": "1.1", + "arrow_up_down": "1.1", + "left_right_arrow": "1.1", + "leftwards_arrow_with_hook": "1.1", + "arrow_right_hook": "1.1", + "arrow_heading_up": "3.2", + "arrow_heading_down": "3.2", + "arrows_clockwise": "6.0", + "arrows_counterclockwise": "6.0", + "back": "6.0", + "end": "6.0", + "on": "6.0", + "soon": "6.0", + "top": "6.0", + "place_of_worship": "8.0", + "worship_symbol": "8.0", + "atom": "4.1", + "atom_symbol": "4.1", + "om_symbol": "7.0", + "star_of_david": "1.1", + "wheel_of_dharma": "1.1", + "yin_yang": "1.1", + "cross": "1.1", + "latin_cross": "1.1", + "orthodox_cross": "1.1", + "star_and_crescent": "1.1", + "peace": "1.1", + "peace_symbol": "1.1", + "menorah": "8.0", + "six_pointed_star": "6.0", + "aries": "1.1", + "taurus": "1.1", + "gemini": "1.1", + "cancer": "1.1", + "leo": "1.1", + "virgo": "1.1", + "libra": "1.1", + "scorpius": "1.1", + "sagittarius": "1.1", + "capricorn": "1.1", + "aquarius": "1.1", + "pisces": "1.1", + "ophiuchus": "6.0", + "twisted_rightwards_arrows": "6.0", + "repeat": "6.0", + "repeat_one": "6.0", + "arrow_forward": "1.1", + "fast_forward": "6.0", + "track_next": "6.0", + "next_track": "6.0", + "play_pause": "6.0", + "arrow_backward": "1.1", + "rewind": "6.0", + "track_previous": "6.0", + "previous_track": "6.0", + "arrow_up_small": "6.0", + "arrow_double_up": "6.0", + "arrow_down_small": "6.0", + "arrow_double_down": "6.0", + "pause_button": "7.0", + "double_vertical_bar": "7.0", + "stop_button": "7.0", + "record_button": "7.0", + "eject": "4.0", + "eject_symbol": "4.0", + "cinema": "6.0", + "low_brightness": "6.0", + "high_brightness": "6.0", + "signal_strength": "6.0", + "vibration_mode": "6.0", + "mobile_phone_off": "6.0", + "recycle": "3.2", + "name_badge": "6.0", + "fleur-de-lis": "4.1", + "beginner": "6.0", + "trident": "6.0", + "o": "5.2", + "white_check_mark": "6.0", + "ballot_box_with_check": "1.1", + "heavy_check_mark": "1.1", + "heavy_multiplication_x": "1.1", + "x": "6.0", + "negative_squared_cross_mark": "6.0", + "heavy_plus_sign": "6.0", + "heavy_minus_sign": "6.0", + "heavy_division_sign": "6.0", + "curly_loop": "6.0", + "loop": "6.0", + "part_alternation_mark": "3.2", + "eight_spoked_asterisk": "1.1", + "eight_pointed_black_star": "1.1", + "sparkle": "1.1", + "bangbang": "1.1", + "interrobang": "3.0", + "question": "6.0", + "grey_question": "6.0", + "grey_exclamation": "6.0", + "exclamation": "5.2", + "wavy_dash": "1.1", + "copyright": "1.1", + "registered": "1.1", + "tm": "1.1", + "hash": "3.0", + "asterisk": "3.0", + "keycap_asterisk": "3.0", + "zero": "3.0", + "one": "3.0", + "two": "3.0", + "three": "3.0", + "four": "3.0", + "five": "3.0", + "six": "3.0", + "seven": "3.0", + "eight": "3.0", + "nine": "3.0", + "keycap_ten": "6.0", + "capital_abcd": "6.0", + "abcd": "6.0", + "symbols": "6.0", + "abc": "6.0", + "a": "6.0", + "ab": "6.0", + "b": "6.0", + "cl": "6.0", + "cool": "6.0", + "free": "6.0", + "information_source": "3.0", + "id": "6.0", + "m": "1.1", + "new": "6.0", + "ng": "6.0", + "o2": "6.0", + "ok": "6.0", + "parking": "5.2", + "sos": "6.0", + "up": "6.0", + "vs": "6.0", + "koko": "6.0", + "sa": "6.0", + "u6708": "6.0", + "u6709": "6.0", + "u6307": "5.2", + "ideograph_advantage": "6.0", + "u5272": "6.0", + "u7121": "5.2", + "u7981": "6.0", + "accept": "6.0", + "u7533": "6.0", + "u5408": "6.0", + "u7a7a": "6.0", + "congratulations": "1.1", + "secret": "1.1", + "u55b6": "6.0", + "u6e80": "6.0", + "black_small_square": "1.1", + "white_small_square": "1.1", + "white_medium_square": "3.2", + "black_medium_square": "3.2", + "white_medium_small_square": "3.2", + "black_medium_small_square": "3.2", + "black_large_square": "5.1", + "white_large_square": "5.1", + "large_orange_diamond": "6.0", + "large_blue_diamond": "6.0", + "small_orange_diamond": "6.0", + "small_blue_diamond": "6.0", + "small_red_triangle": "6.0", + "small_red_triangle_down": "6.0", + "diamond_shape_with_a_dot_inside": "6.0", + "radio_button": "6.0", + "black_square_button": "6.0", + "white_square_button": "6.0", + "white_circle": "4.1", + "black_circle": "4.1", + "red_circle": "6.0", + "blue_circle": "6.0", + "checkered_flag": "6.0", + "triangular_flag_on_post": "6.0", + "crossed_flags": "6.0", + "flag_black": "6.0", + "waving_black_flag": "6.0", + "flag_white": "6.0", + "waving_white_flag": "6.0", + "rainbow_flag": "6.0", + "gay_pride_flag": "6.0", + "flag_ac": "6.0", + "ac": "6.0", + "flag_ad": "6.0", + "ad": "6.0", + "flag_ae": "6.0", + "ae": "6.0", + "flag_af": "6.0", + "af": "6.0", + "flag_ag": "6.0", + "ag": "6.0", + "flag_ai": "6.0", + "ai": "6.0", + "flag_al": "6.0", + "al": "6.0", + "flag_am": "6.0", + "am": "6.0", + "flag_ao": "6.0", + "ao": "6.0", + "flag_aq": "6.0", + "aq": "6.0", + "flag_ar": "6.0", + "ar": "6.0", + "flag_as": "6.0", + "as": "6.0", + "flag_at": "6.0", + "at": "6.0", + "flag_au": "6.0", + "au": "6.0", + "flag_aw": "6.0", + "aw": "6.0", + "flag_ax": "6.0", + "ax": "6.0", + "flag_az": "6.0", + "az": "6.0", + "flag_ba": "6.0", + "ba": "6.0", + "flag_bb": "6.0", + "bb": "6.0", + "flag_bd": "6.0", + "bd": "6.0", + "flag_be": "6.0", + "be": "6.0", + "flag_bf": "6.0", + "bf": "6.0", + "flag_bg": "6.0", + "bg": "6.0", + "flag_bh": "6.0", + "bh": "6.0", + "flag_bi": "6.0", + "bi": "6.0", + "flag_bj": "6.0", + "bj": "6.0", + "flag_bl": "6.0", + "bl": "6.0", + "flag_bm": "6.0", + "bm": "6.0", + "flag_bn": "6.0", + "bn": "6.0", + "flag_bo": "6.0", + "bo": "6.0", + "flag_bq": "6.0", + "bq": "6.0", + "flag_br": "6.0", + "br": "6.0", + "flag_bs": "6.0", + "bs": "6.0", + "flag_bt": "6.0", + "bt": "6.0", + "flag_bv": "6.0", + "bv": "6.0", + "flag_bw": "6.0", + "bw": "6.0", + "flag_by": "6.0", + "by": "6.0", + "flag_bz": "6.0", + "bz": "6.0", + "flag_ca": "6.0", + "ca": "6.0", + "flag_cc": "6.0", + "cc": "6.0", + "flag_cd": "6.0", + "congo": "6.0", + "flag_cf": "6.0", + "cf": "6.0", + "flag_cg": "6.0", + "cg": "6.0", + "flag_ch": "6.0", + "ch": "6.0", + "flag_ci": "6.0", + "ci": "6.0", + "flag_ck": "6.0", + "ck": "6.0", + "flag_cl": "6.0", + "chile": "6.0", + "flag_cm": "6.0", + "cm": "6.0", + "flag_cn": "6.0", + "cn": "6.0", + "flag_co": "6.0", + "co": "6.0", + "flag_cp": "6.0", + "cp": "6.0", + "flag_cr": "6.0", + "cr": "6.0", + "flag_cu": "6.0", + "cu": "6.0", + "flag_cv": "6.0", + "cv": "6.0", + "flag_cw": "6.0", + "cw": "6.0", + "flag_cx": "6.0", + "cx": "6.0", + "flag_cy": "6.0", + "cy": "6.0", + "flag_cz": "6.0", + "cz": "6.0", + "flag_de": "6.0", + "de": "6.0", + "flag_dg": "6.0", + "dg": "6.0", + "flag_dj": "6.0", + "dj": "6.0", + "flag_dk": "6.0", + "dk": "6.0", + "flag_dm": "6.0", + "dm": "6.0", + "flag_do": "6.0", + "do": "6.0", + "flag_dz": "6.0", + "dz": "6.0", + "flag_ea": "6.0", + "ea": "6.0", + "flag_ec": "6.0", + "ec": "6.0", + "flag_ee": "6.0", + "ee": "6.0", + "flag_eg": "6.0", + "eg": "6.0", + "flag_eh": "6.0", + "eh": "6.0", + "flag_er": "6.0", + "er": "6.0", + "flag_es": "6.0", + "es": "6.0", + "flag_et": "6.0", + "et": "6.0", + "flag_eu": "6.0", + "eu": "6.0", + "flag_fi": "6.0", + "fi": "6.0", + "flag_fj": "6.0", + "fj": "6.0", + "flag_fk": "6.0", + "fk": "6.0", + "flag_fm": "6.0", + "fm": "6.0", + "flag_fo": "6.0", + "fo": "6.0", + "flag_fr": "6.0", + "fr": "6.0", + "flag_ga": "6.0", + "ga": "6.0", + "flag_gb": "6.0", + "gb": "6.0", + "flag_gd": "6.0", + "gd": "6.0", + "flag_ge": "6.0", + "ge": "6.0", + "flag_gf": "6.0", + "gf": "6.0", + "flag_gg": "6.0", + "gg": "6.0", + "flag_gh": "6.0", + "gh": "6.0", + "flag_gi": "6.0", + "gi": "6.0", + "flag_gl": "6.0", + "gl": "6.0", + "flag_gm": "6.0", + "gm": "6.0", + "flag_gn": "6.0", + "gn": "6.0", + "flag_gp": "6.0", + "gp": "6.0", + "flag_gq": "6.0", + "gq": "6.0", + "flag_gr": "6.0", + "gr": "6.0", + "flag_gs": "6.0", + "gs": "6.0", + "flag_gt": "6.0", + "gt": "6.0", + "flag_gu": "6.0", + "gu": "6.0", + "flag_gw": "6.0", + "gw": "6.0", + "flag_gy": "6.0", + "gy": "6.0", + "flag_hk": "6.0", + "hk": "6.0", + "flag_hm": "6.0", + "hm": "6.0", + "flag_hn": "6.0", + "hn": "6.0", + "flag_hr": "6.0", + "hr": "6.0", + "flag_ht": "6.0", + "ht": "6.0", + "flag_hu": "6.0", + "hu": "6.0", + "flag_ic": "6.0", + "ic": "6.0", + "flag_id": "6.0", + "indonesia": "6.0", + "flag_ie": "6.0", + "ie": "6.0", + "flag_il": "6.0", + "il": "6.0", + "flag_im": "6.0", + "im": "6.0", + "flag_in": "6.0", + "in": "6.0", + "flag_io": "6.0", + "io": "6.0", + "flag_iq": "6.0", + "iq": "6.0", + "flag_ir": "6.0", + "ir": "6.0", + "flag_is": "6.0", + "is": "6.0", + "flag_it": "6.0", + "it": "6.0", + "flag_je": "6.0", + "je": "6.0", + "flag_jm": "6.0", + "jm": "6.0", + "flag_jo": "6.0", + "jo": "6.0", + "flag_jp": "6.0", + "jp": "6.0", + "flag_ke": "6.0", + "ke": "6.0", + "flag_kg": "6.0", + "kg": "6.0", + "flag_kh": "6.0", + "kh": "6.0", + "flag_ki": "6.0", + "ki": "6.0", + "flag_km": "6.0", + "km": "6.0", + "flag_kn": "6.0", + "kn": "6.0", + "flag_kp": "6.0", + "kp": "6.0", + "flag_kr": "6.0", + "kr": "6.0", + "flag_kw": "6.0", + "kw": "6.0", + "flag_ky": "6.0", + "ky": "6.0", + "flag_kz": "6.0", + "kz": "6.0", + "flag_la": "6.0", + "la": "6.0", + "flag_lb": "6.0", + "lb": "6.0", + "flag_lc": "6.0", + "lc": "6.0", + "flag_li": "6.0", + "li": "6.0", + "flag_lk": "6.0", + "lk": "6.0", + "flag_lr": "6.0", + "lr": "6.0", + "flag_ls": "6.0", + "ls": "6.0", + "flag_lt": "6.0", + "lt": "6.0", + "flag_lu": "6.0", + "lu": "6.0", + "flag_lv": "6.0", + "lv": "6.0", + "flag_ly": "6.0", + "ly": "6.0", + "flag_ma": "6.0", + "ma": "6.0", + "flag_mc": "6.0", + "mc": "6.0", + "flag_md": "6.0", + "md": "6.0", + "flag_me": "6.0", + "me": "6.0", + "flag_mf": "6.0", + "mf": "6.0", + "flag_mg": "6.0", + "mg": "6.0", + "flag_mh": "6.0", + "mh": "6.0", + "flag_mk": "6.0", + "mk": "6.0", + "flag_ml": "6.0", + "ml": "6.0", + "flag_mm": "6.0", + "mm": "6.0", + "flag_mn": "6.0", + "mn": "6.0", + "flag_mo": "6.0", + "mo": "6.0", + "flag_mp": "6.0", + "mp": "6.0", + "flag_mq": "6.0", + "mq": "6.0", + "flag_mr": "6.0", + "mr": "6.0", + "flag_ms": "6.0", + "ms": "6.0", + "flag_mt": "6.0", + "mt": "6.0", + "flag_mu": "6.0", + "mu": "6.0", + "flag_mv": "6.0", + "mv": "6.0", + "flag_mw": "6.0", + "mw": "6.0", + "flag_mx": "6.0", + "mx": "6.0", + "flag_my": "6.0", + "my": "6.0", + "flag_mz": "6.0", + "mz": "6.0", + "flag_na": "6.0", + "na": "6.0", + "flag_nc": "6.0", + "nc": "6.0", + "flag_ne": "6.0", + "ne": "6.0", + "flag_nf": "6.0", + "nf": "6.0", + "flag_ng": "6.0", + "nigeria": "6.0", + "flag_ni": "6.0", + "ni": "6.0", + "flag_nl": "6.0", + "nl": "6.0", + "flag_no": "6.0", + "no": "6.0", + "flag_np": "6.0", + "np": "6.0", + "flag_nr": "6.0", + "nr": "6.0", + "flag_nu": "6.0", + "nu": "6.0", + "flag_nz": "6.0", + "nz": "6.0", + "flag_om": "6.0", + "om": "6.0", + "flag_pa": "6.0", + "pa": "6.0", + "flag_pe": "6.0", + "pe": "6.0", + "flag_pf": "6.0", + "pf": "6.0", + "flag_pg": "6.0", + "pg": "6.0", + "flag_ph": "6.0", + "ph": "6.0", + "flag_pk": "6.0", + "pk": "6.0", + "flag_pl": "6.0", + "pl": "6.0", + "flag_pm": "6.0", + "pm": "6.0", + "flag_pn": "6.0", + "pn": "6.0", + "flag_pr": "6.0", + "pr": "6.0", + "flag_ps": "6.0", + "ps": "6.0", + "flag_pt": "6.0", + "pt": "6.0", + "flag_pw": "6.0", + "pw": "6.0", + "flag_py": "6.0", + "py": "6.0", + "flag_qa": "6.0", + "qa": "6.0", + "flag_re": "6.0", + "re": "6.0", + "flag_ro": "6.0", + "ro": "6.0", + "flag_rs": "6.0", + "rs": "6.0", + "flag_ru": "6.0", + "ru": "6.0", + "flag_rw": "6.0", + "rw": "6.0", + "flag_sa": "6.0", + "saudiarabia": "6.0", + "saudi": "6.0", + "flag_sb": "6.0", + "sb": "6.0", + "flag_sc": "6.0", + "sc": "6.0", + "flag_sd": "6.0", + "sd": "6.0", + "flag_se": "6.0", + "se": "6.0", + "flag_sg": "6.0", + "sg": "6.0", + "flag_sh": "6.0", + "sh": "6.0", + "flag_si": "6.0", + "si": "6.0", + "flag_sj": "6.0", + "sj": "6.0", + "flag_sk": "6.0", + "sk": "6.0", + "flag_sl": "6.0", + "sl": "6.0", + "flag_sm": "6.0", + "sm": "6.0", + "flag_sn": "6.0", + "sn": "6.0", + "flag_so": "6.0", + "so": "6.0", + "flag_sr": "6.0", + "sr": "6.0", + "flag_ss": "6.0", + "ss": "6.0", + "flag_st": "6.0", + "st": "6.0", + "flag_sv": "6.0", + "sv": "6.0", + "flag_sx": "6.0", + "sx": "6.0", + "flag_sy": "6.0", + "sy": "6.0", + "flag_sz": "6.0", + "sz": "6.0", + "flag_ta": "6.0", + "ta": "6.0", + "flag_tc": "6.0", + "tc": "6.0", + "flag_td": "6.0", + "td": "6.0", + "flag_tf": "6.0", + "tf": "6.0", + "flag_tg": "6.0", + "tg": "6.0", + "flag_th": "6.0", + "th": "6.0", + "flag_tj": "6.0", + "tj": "6.0", + "flag_tk": "6.0", + "tk": "6.0", + "flag_tl": "6.0", + "tl": "6.0", + "flag_tm": "6.0", + "turkmenistan": "6.0", + "flag_tn": "6.0", + "tn": "6.0", + "flag_to": "6.0", + "to": "6.0", + "flag_tr": "6.0", + "tr": "6.0", + "flag_tt": "6.0", + "tt": "6.0", + "flag_tv": "6.0", + "tuvalu": "6.0", + "flag_tw": "6.0", + "tw": "6.0", + "flag_tz": "6.0", + "tz": "6.0", + "flag_ua": "6.0", + "ua": "6.0", + "flag_ug": "6.0", + "ug": "6.0", + "flag_um": "6.0", + "um": "6.0", + "flag_us": "6.0", + "us": "6.0", + "flag_uy": "6.0", + "uy": "6.0", + "flag_uz": "6.0", + "uz": "6.0", + "flag_va": "6.0", + "va": "6.0", + "flag_vc": "6.0", + "vc": "6.0", + "flag_ve": "6.0", + "ve": "6.0", + "flag_vg": "6.0", + "vg": "6.0", + "flag_vi": "6.0", + "vi": "6.0", + "flag_vn": "6.0", + "vn": "6.0", + "flag_vu": "6.0", + "vu": "6.0", + "flag_wf": "6.0", + "wf": "6.0", + "flag_ws": "6.0", + "ws": "6.0", + "flag_xk": "6.0", + "xk": "6.0", + "flag_ye": "6.0", + "ye": "6.0", + "flag_yt": "6.0", + "yt": "6.0", + "flag_za": "6.0", + "za": "6.0", + "flag_zm": "6.0", + "zm": "6.0", + "flag_zw": "6.0", + "zw": "6.0", + "regional_indicator_z": "6.0", + "regional_indicator_y": "6.0", + "regional_indicator_x": "6.0", + "regional_indicator_w": "6.0", + "regional_indicator_v": "6.0", + "regional_indicator_u": "6.0", + "regional_indicator_t": "6.0", + "regional_indicator_s": "6.0", + "regional_indicator_r": "6.0", + "regional_indicator_q": "6.0", + "regional_indicator_p": "6.0", + "regional_indicator_o": "6.0", + "regional_indicator_n": "6.0", + "regional_indicator_m": "6.0", + "regional_indicator_l": "6.0", + "regional_indicator_k": "6.0", + "regional_indicator_j": "6.0", + "regional_indicator_i": "6.0", + "regional_indicator_h": "6.0", + "regional_indicator_g": "6.0", + "regional_indicator_f": "6.0", + "regional_indicator_e": "6.0", + "regional_indicator_d": "6.0", + "regional_indicator_c": "6.0", + "regional_indicator_b": "6.0", + "regional_indicator_a": "6.0", + "large_blue_circle": "6.0", + "ten": "6.0" +}
\ No newline at end of file diff --git a/lib/gitlab/ci/status/pipeline/blocked.rb b/lib/gitlab/ci/status/pipeline/blocked.rb new file mode 100644 index 00000000000..a250c3fcb41 --- /dev/null +++ b/lib/gitlab/ci/status/pipeline/blocked.rb @@ -0,0 +1,23 @@ +module Gitlab + module Ci + module Status + module Pipeline + class Blocked < SimpleDelegator + include Status::Extended + + def text + 'blocked' + end + + def label + 'waiting for manual action' + end + + def self.matches?(pipeline, user) + pipeline.blocked? + end + end + end + end + end +end diff --git a/lib/gitlab/ci/status/pipeline/factory.rb b/lib/gitlab/ci/status/pipeline/factory.rb index 13c8343b12a..17f9a75f436 100644 --- a/lib/gitlab/ci/status/pipeline/factory.rb +++ b/lib/gitlab/ci/status/pipeline/factory.rb @@ -4,7 +4,8 @@ module Gitlab module Pipeline class Factory < Status::Factory def self.extended_statuses - [Status::SuccessWarning] + [[Status::SuccessWarning, + Status::Pipeline::Blocked]] end def self.common_helpers diff --git a/lib/gitlab/emoji.rb b/lib/gitlab/emoji.rb index 42703545c4f..35871fd1b7b 100644 --- a/lib/gitlab/emoji.rb +++ b/lib/gitlab/emoji.rb @@ -31,7 +31,7 @@ module Gitlab end def emoji_unicode_version(name) - @emoji_unicode_versions_by_name ||= JSON.parse(File.read(Rails.root.join('node_modules', 'emoji-unicode-version', 'emoji-unicode-version-map.json'))) + @emoji_unicode_versions_by_name ||= JSON.parse(File.read(Rails.root.join('fixtures', 'emojis', 'emoji-unicode-version-map.json'))) @emoji_unicode_versions_by_name[name] end diff --git a/lib/gitlab/github_import/pull_request_formatter.rb b/lib/gitlab/github_import/pull_request_formatter.rb index 4ea0200e89b..28812fd0cb9 100644 --- a/lib/gitlab/github_import/pull_request_formatter.rb +++ b/lib/gitlab/github_import/pull_request_formatter.rb @@ -38,7 +38,11 @@ module Gitlab def source_branch_name @source_branch_name ||= begin - source_branch_exists? ? source_branch_ref : "pull/#{number}/#{source_branch_ref}" + if cross_project? + "pull/#{number}/#{source_branch_repo.full_name}/#{source_branch_ref}" + else + source_branch_exists? ? source_branch_ref : "pull/#{number}/#{source_branch_ref}" + end end end @@ -52,6 +56,10 @@ module Gitlab end end + def cross_project? + source_branch.repo.id != target_branch.repo.id + end + private def state diff --git a/lib/tasks/gemojione.rake b/lib/tasks/gemojione.rake index 1f93b5a4dd2..5293f5af12d 100644 --- a/lib/tasks/gemojione.rake +++ b/lib/tasks/gemojione.rake @@ -1,9 +1,12 @@ namespace :gemojione do desc 'Generates Emoji SHA256 digests' - task digests: :environment do + task digests: ['yarn:check', 'environment'] do require 'digest/sha2' require 'json' + # We don't have `node_modules` available in built versions of GitLab + FileUtils.cp_r(Rails.root.join('node_modules', 'emoji-unicode-version', 'emoji-unicode-version-map.json'), File.join(Rails.root, 'fixtures', 'emojis')) + dir = Gemojione.images_path resultant_emoji_map = {} diff --git a/spec/factories/ci/pipelines.rb b/spec/factories/ci/pipelines.rb index 77404f46c92..b67c96bc00d 100644 --- a/spec/factories/ci/pipelines.rb +++ b/spec/factories/ci/pipelines.rb @@ -40,6 +40,14 @@ FactoryGirl.define do trait :invalid do config(rspec: nil) end + + trait :blocked do + status :manual + end + + trait :success do + status :success + end end end end diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index c6f91e05d83..0db2fe04edd 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -38,7 +38,7 @@ FactoryGirl.define do trait :empty_repo do after(:create) do |project| - project.create_repository + raise "Failed to create repository!" unless project.create_repository # We delete hooks so that gitlab-shell will not try to authenticate with # an API that isn't running @@ -48,7 +48,7 @@ FactoryGirl.define do trait :broken_repo do after(:create) do |project| - project.create_repository + raise "Failed to create repository!" unless project.create_repository FileUtils.rm_r(File.join(project.repository_storage_path, "#{project.path_with_namespace}.git", 'refs')) end diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb index c2e0612aef8..34d6257f5fd 100644 --- a/spec/features/dashboard/user_filters_projects_spec.rb +++ b/spec/features/dashboard/user_filters_projects_spec.rb @@ -1,26 +1,45 @@ require 'spec_helper' -describe "Dashboard > User filters projects", feature: true do +describe 'Dashboard > User filters projects', :feature do + let(:user) { create(:user) } + let(:project) { create(:project, name: 'Victorialand', namespace: user.namespace) } + let(:user2) { create(:user) } + let(:project2) { create(:project, name: 'Treasure', namespace: user2.namespace) } + + before do + project.team << [user, :master] + + login_as(user) + end + describe 'filtering personal projects' do before do - user = create(:user) - project = create(:project, name: "Victorialand", namespace: user.namespace) - project.team << [user, :master] - - user2 = create(:user) - project2 = create(:project, name: "Treasure", namespace: user2.namespace) project2.team << [user, :developer] - login_as(user) visit dashboard_projects_path end it 'filters by projects "Owned by me"' do - click_link "Owned by me" + click_link 'Owned by me' expect(page).to have_css('.is-active', text: 'Owned by me') expect(page).to have_content('Victorialand') expect(page).not_to have_content('Treasure') end end + + describe 'filtering starred projects', :js do + before do + user.toggle_star(project) + + visit dashboard_projects_path + end + + it 'returns message when starred projects fitler returns no results' do + fill_in 'project-filter-form-field', with: 'Beta\n' + + expect(page).to have_content('No projects found') + expect(page).not_to have_content('You don\'t have starred projects yet') + end + end end diff --git a/spec/features/dashboard_issues_spec.rb b/spec/features/dashboard_issues_spec.rb index aa75e1140f6..8c61cdebc4b 100644 --- a/spec/features/dashboard_issues_spec.rb +++ b/spec/features/dashboard_issues_spec.rb @@ -48,7 +48,7 @@ describe "Dashboard Issues filtering", feature: true, js: true do it 'updates atom feed link' do visit_issues(milestone_title: '', assignee_id: user.id) - link = find('.nav-controls a', text: 'Subscribe') + link = find('.nav-controls a[title="Subscribe"]') params = CGI.parse(URI.parse(link[:href]).query) auto_discovery_link = find('link[type="application/atom+xml"]', visible: false) auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query) diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb index 0324fcad0a0..85ffffe4b6d 100644 --- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb @@ -1,8 +1,7 @@ require 'rails_helper' -describe 'Dropdown milestone', js: true, feature: true do +describe 'Dropdown milestone', :feature, :js do include FilteredSearchHelpers - include WaitForAjax let!(:project) { create(:empty_project) } let!(:user) { create(:user) } @@ -15,18 +14,10 @@ describe 'Dropdown milestone', js: true, feature: true do let(:filtered_search) { find('.filtered-search') } let(:js_dropdown_milestone) { '#js-dropdown-milestone' } - - def send_keys_to_filtered_search(input) - input.split("").each do |i| - filtered_search.send_keys(i) - sleep 3 - wait_for_ajax - sleep 3 - end - end + let(:filter_dropdown) { find("#{js_dropdown_milestone} .filter-dropdown") } def dropdown_milestone_size - page.all('#js-dropdown-milestone .filter-dropdown .filter-dropdown-item').size + filter_dropdown.all('.filter-dropdown-item').size end def click_milestone(text) @@ -65,13 +56,14 @@ describe 'Dropdown milestone', js: true, feature: true do end it 'should hide loading indicator when loaded' do - send_keys_to_filtered_search('milestone:') + filtered_search.set('milestone:') - expect(page).not_to have_css('#js-dropdown-milestone .filter-dropdown-loading') + expect(find(js_dropdown_milestone)).to have_css('.filter-dropdown-loading') + expect(find(js_dropdown_milestone)).not_to have_css('.filter-dropdown-loading') end it 'should load all the milestones when opened' do - send_keys_to_filtered_search('milestone:') + filtered_search.set('milestone:') expect(dropdown_milestone_size).to be > 0 end @@ -79,41 +71,48 @@ describe 'Dropdown milestone', js: true, feature: true do describe 'filtering' do before do - filtered_search.set('milestone') + filtered_search.set('milestone:') + + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(milestone.title) + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(uppercase_milestone.title) + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(two_words_milestone.title) + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(wont_fix_milestone.title) + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(special_milestone.title) + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(long_milestone.title) end it 'filters by name' do - send_keys_to_filtered_search(':v1') + filtered_search.send_keys('v1') expect(dropdown_milestone_size).to eq(1) end it 'filters by case insensitive name' do - send_keys_to_filtered_search(':V1') + filtered_search.send_keys('V1') expect(dropdown_milestone_size).to eq(1) end it 'filters by name with symbol' do - send_keys_to_filtered_search(':%v1') + filtered_search.send_keys('%v1') expect(dropdown_milestone_size).to eq(1) end it 'filters by case insensitive name with symbol' do - send_keys_to_filtered_search(':%V1') + filtered_search.send_keys('%V1') expect(dropdown_milestone_size).to eq(1) end it 'filters by special characters' do - send_keys_to_filtered_search(':(+') + filtered_search.send_keys('(+') expect(dropdown_milestone_size).to eq(1) end it 'filters by special characters with symbol' do - send_keys_to_filtered_search(':%(+') + filtered_search.send_keys('%(+') expect(dropdown_milestone_size).to eq(1) end @@ -122,6 +121,13 @@ describe 'Dropdown milestone', js: true, feature: true do describe 'selecting from dropdown' do before do filtered_search.set('milestone:') + + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(milestone.title) + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(uppercase_milestone.title) + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(two_words_milestone.title) + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(wont_fix_milestone.title) + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(special_milestone.title) + expect(find("#{js_dropdown_milestone} .filter-dropdown")).to have_content(long_milestone.title) end it 'fills in the milestone name when the milestone has not been filled' do @@ -133,7 +139,7 @@ describe 'Dropdown milestone', js: true, feature: true do end it 'fills in the milestone name when the milestone is partially filled' do - send_keys_to_filtered_search('v') + filtered_search.send_keys('v') click_milestone(milestone.title) expect(page).to have_css(js_dropdown_milestone, visible: false) @@ -232,16 +238,14 @@ describe 'Dropdown milestone', js: true, feature: true do describe 'caching requests' do it 'caches requests after the first load' do - filtered_search.set('milestone') - send_keys_to_filtered_search(':') + filtered_search.set('milestone:') initial_size = dropdown_milestone_size expect(initial_size).to be > 0 create(:milestone, project: project) find('.filtered-search-input-container .clear-search').click - filtered_search.set('milestone') - send_keys_to_filtered_search(':') + filtered_search.set('milestone:') expect(dropdown_milestone_size).to eq(initial_size) end diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb index a78dbaf53ed..96e87c82d2c 100644 --- a/spec/features/issues/filtered_search/visual_tokens_spec.rb +++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb @@ -242,6 +242,23 @@ describe 'Visual tokens', js: true, feature: true do end end + describe 'editing a search term while editing another filter token' do + before do + input_filtered_search('author assignee:', submit: false) + first('.tokens-container .filtered-search-term').double_click + end + + it 'opens hint dropdown' do + expect(page).to have_css('#js-dropdown-hint', visible: true) + end + + it 'opens author dropdown' do + find('#js-dropdown-hint .filter-dropdown .filter-dropdown-item', text: 'author').click + + expect(page).to have_css('#js-dropdown-author', visible: true) + end + end + describe 'add new token after editing existing token' do before do input_filtered_search('author:@root assignee:none', submit: false) @@ -319,4 +336,17 @@ describe 'Visual tokens', js: true, feature: true do expect(token.find('.name').text).to eq('Author') end end + + describe 'search using incomplete visual tokens' do + before do + input_filtered_search('author:@root assignee:none', extra_space: false) + end + + it 'tokenizes the search term to complete visual token' do + expect_tokens([ + { name: 'author', value: '@root' }, + { name: 'assignee', value: 'none' } + ]) + end + end end diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb new file mode 100644 index 00000000000..7df102067d6 --- /dev/null +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -0,0 +1,136 @@ +require 'spec_helper' + +feature 'Diff note avatars', feature: true, js: true do + include WaitForAjax + + let(:user) { create(:user) } + let(:project) { create(:project, :public) } + let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: user, title: "Bug NS-04") } + let(:path) { "files/ruby/popen.rb" } + let(:position) do + Gitlab::Diff::Position.new( + old_path: path, + new_path: path, + old_line: nil, + new_line: 9, + diff_refs: merge_request.diff_refs + ) + end + let!(:note) { create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) } + + before do + project.team << [user, :master] + login_as user + end + + %w(inline parallel).each do |view| + context "#{view} view" do + before do + visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: view) + + wait_for_ajax + end + + it 'shows note avatar' do + page.within find("[id='#{position.line_code(project.repository)}']") do + find('.diff-notes-collapse').click + + expect(page).to have_selector('img.js-diff-comment-avatar', count: 1) + end + end + + it 'shows comment on note avatar' do + page.within find("[id='#{position.line_code(project.repository)}']") do + find('.diff-notes-collapse').click + + expect(first('img.js-diff-comment-avatar')["title"]).to eq("#{note.author.name}: #{note.note.truncate(17)}") + end + end + + it 'toggles comments when clicking avatar' do + page.within find("[id='#{position.line_code(project.repository)}']") do + find('.diff-notes-collapse').click + end + + expect(page).to have_selector('.notes_holder', visible: false) + + page.within find("[id='#{position.line_code(project.repository)}']") do + first('img.js-diff-comment-avatar').click + end + + expect(page).to have_selector('.notes_holder') + end + + it 'removes avatar when note is deleted' do + page.within find(".note-row-#{note.id}") do + find('.js-note-delete').click + end + + wait_for_ajax + + page.within find("[id='#{position.line_code(project.repository)}']") do + expect(page).not_to have_selector('img.js-diff-comment-avatar') + end + end + + it 'adds avatar when commenting' do + click_button 'Reply...' + + page.within '.js-discussion-note-form' do + find('.js-note-text').native.send_keys('Test') + + click_button 'Comment' + + wait_for_ajax + end + + page.within find("[id='#{position.line_code(project.repository)}']") do + find('.diff-notes-collapse').click + + expect(page).to have_selector('img.js-diff-comment-avatar', count: 2) + end + end + + it 'adds multiple comments' do + 3.times do + click_button 'Reply...' + + page.within '.js-discussion-note-form' do + find('.js-note-text').native.send_keys('Test') + + find('.js-comment-button').trigger 'click' + + wait_for_ajax + end + end + + page.within find("[id='#{position.line_code(project.repository)}']") do + find('.diff-notes-collapse').click + + expect(page).to have_selector('img.js-diff-comment-avatar', count: 3) + expect(find('.diff-comments-more-count')).to have_content '+1' + end + end + + context 'multiple comments' do + before do + create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) + create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) + create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) + + visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: view) + + wait_for_ajax + end + + it 'shows extra comment count' do + page.within find("[id='#{position.line_code(project.repository)}']") do + find('.diff-notes-collapse').click + + expect(find('.diff-comments-more-count')).to have_content '+1' + end + end + end + end + end +end diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js index f4b1d777203..d8517e4d3d1 100644 --- a/spec/javascripts/awards_handler_spec.js +++ b/spec/javascripts/awards_handler_spec.js @@ -46,9 +46,6 @@ const AwardsHandler = require('~/awards_handler'); isEmojiMenuBuilt = true; resolve(); }); - - // Fail after 1 second - setTimeout(reject, 1000); } }); }; diff --git a/spec/javascripts/diff_comments_store_spec.js b/spec/javascripts/diff_comments_store_spec.js index f956394ef53..84cf98c930a 100644 --- a/spec/javascripts/diff_comments_store_spec.js +++ b/spec/javascripts/diff_comments_store_spec.js @@ -7,7 +7,16 @@ require('~/diff_notes/stores/comments'); (() => { function createDiscussion(noteId = 1, resolved = true) { - CommentsStore.create('a', noteId, true, resolved, 'test'); + CommentsStore.create({ + discussionId: 'a', + noteId, + canResolve: true, + resolved, + resolvedBy: 'test', + authorName: 'test', + authorAvatar: 'test', + noteTruncated: 'test...', + }); } beforeEach(() => { diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js index e7530f61385..8d25500b9fd 100644 --- a/spec/javascripts/issue_spec.js +++ b/spec/javascripts/issue_spec.js @@ -1,10 +1,9 @@ /* eslint-disable space-before-function-paren, no-var, one-var, one-var-declaration-per-line, no-use-before-define, comma-dangle, max-len */ -/* global Issue */ +import Issue from '~/issue'; require('~/lib/utils/text_utility'); -require('~/issue'); -(function() { +describe('Issue', function() { var INVALID_URL = 'http://goesnowhere.nothing/whereami'; var $boxClosed, $boxOpen, $btnClose, $btnReopen; @@ -59,28 +58,26 @@ require('~/issue'); expect($btnReopen).toHaveText('Reopen issue'); } - describe('Issue', function() { - describe('task lists', function() { - beforeEach(function() { - loadFixtures('issues/issue-with-task-list.html.raw'); - this.issue = new Issue(); - }); - - it('modifies the Markdown field', function() { - spyOn(jQuery, 'ajax').and.stub(); - $('input[type=checkbox]').attr('checked', true).trigger('change'); - expect($('.js-task-list-field').val()).toBe('- [x] Task List Item'); - }); + describe('task lists', function() { + beforeEach(function() { + loadFixtures('issues/issue-with-task-list.html.raw'); + this.issue = new Issue(); + }); - it('submits an ajax request on tasklist:changed', function() { - spyOn(jQuery, 'ajax').and.callFake(function(req) { - expect(req.type).toBe('PATCH'); - expect(req.url).toBe(gl.TEST_HOST + '/frontend-fixtures/issues-project/issues/1.json'); // eslint-disable-line prefer-template - expect(req.data.issue.description).not.toBe(null); - }); + it('modifies the Markdown field', function() { + spyOn(jQuery, 'ajax').and.stub(); + $('input[type=checkbox]').attr('checked', true).trigger('change'); + expect($('.js-task-list-field').val()).toBe('- [x] Task List Item'); + }); - $('.js-task-list-field').trigger('tasklist:changed'); + it('submits an ajax request on tasklist:changed', function() { + spyOn(jQuery, 'ajax').and.callFake(function(req) { + expect(req.type).toBe('PATCH'); + expect(req.url).toBe(gl.TEST_HOST + '/frontend-fixtures/issues-project/issues/1.json'); // eslint-disable-line prefer-template + expect(req.data.issue.description).not.toBe(null); }); + + $('.js-task-list-field').trigger('tasklist:changed'); }); }); @@ -165,4 +162,4 @@ require('~/issue'); expect($('.issue_counter')).toHaveText(1); }); }); -}).call(window); +}); diff --git a/spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb b/spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb new file mode 100644 index 00000000000..1a2b952d374 --- /dev/null +++ b/spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe Gitlab::Ci::Status::Pipeline::Blocked do + let(:pipeline) { double('pipeline') } + + subject do + described_class.new(pipeline) + end + + describe '#text' do + it 'overrides status text' do + expect(subject.text).to eq 'blocked' + end + end + + describe '#label' do + it 'overrides status label' do + expect(subject.label).to eq 'waiting for manual action' + end + end + + describe '.matches?' do + let(:user) { double('user') } + subject { described_class.matches?(pipeline, user) } + + context 'when pipeline is blocked' do + let(:pipeline) { create(:ci_pipeline, :blocked) } + + it 'is a correct match' do + expect(subject).to be true + end + end + + context 'when pipeline is not blocked' do + let(:pipeline) { create(:ci_pipeline, :success) } + + it 'does not match' do + expect(subject).to be false + end + end + end +end diff --git a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb index b10a447c27a..dd754b849b2 100644 --- a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb @@ -11,7 +11,8 @@ describe Gitlab::Ci::Status::Pipeline::Factory do end context 'when pipeline has a core status' do - HasStatus::AVAILABLE_STATUSES.each do |simple_status| + (HasStatus::AVAILABLE_STATUSES - [HasStatus::BLOCKED_STATUS]) + .each do |simple_status| context "when core status is #{simple_status}" do let(:pipeline) { create(:ci_pipeline, status: simple_status) } @@ -23,7 +24,7 @@ describe Gitlab::Ci::Status::Pipeline::Factory do expect(factory.core_status).to be_a expected_status end - it 'does not matche extended statuses' do + it 'does not match extended statuses' do expect(factory.extended_statuses).to be_empty end @@ -39,6 +40,27 @@ describe Gitlab::Ci::Status::Pipeline::Factory do end end end + + context "when core status is manual" do + let(:pipeline) { create(:ci_pipeline, status: :manual) } + + it "matches manual core status" do + expect(factory.core_status) + .to be_a Gitlab::Ci::Status::Manual + end + + it 'matches a correct extended statuses' do + expect(factory.extended_statuses) + .to eq [Gitlab::Ci::Status::Pipeline::Blocked] + end + + it 'extends core status with common pipeline methods' do + expect(status).to have_details + expect(status).not_to have_action + expect(status.details_path) + .to include "pipelines/#{pipeline.id}" + end + end end context 'when pipeline has warnings' do diff --git a/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb b/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb index eeef23a61c6..951cbea7857 100644 --- a/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb +++ b/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb @@ -8,9 +8,11 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do let(:repository) { double(id: 1, fork: false) } let(:source_repo) { repository } let(:source_branch) { double(ref: 'branch-merged', repo: source_repo, sha: source_sha) } + let(:forked_source_repo) { double(id: 2, fork: true, name: 'otherproject', full_name: 'company/otherproject') } let(:target_repo) { repository } let(:target_branch) { double(ref: 'master', repo: target_repo, sha: target_sha) } let(:removed_branch) { double(ref: 'removed-branch', repo: source_repo, sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b') } + let(:forked_branch) { double(ref: 'master', repo: forked_source_repo, sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b') } let(:octocat) { double(id: 123456, login: 'octocat', email: 'octocat@example.com') } let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') } let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') } @@ -205,6 +207,14 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do expect(pull_request.source_branch_name).to eq 'pull/1347/removed-branch' end end + + context 'when source branch is from a fork' do + let(:raw_data) { double(base_data.merge(head: forked_branch)) } + + it 'prefixes branch name with pull request number and project with namespace to avoid collision' do + expect(pull_request.source_branch_name).to eq 'pull/1347/company/otherproject/master' + end + end end shared_examples 'Gitlab::GithubImport::PullRequestFormatter#target_branch_name' do @@ -271,6 +281,24 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do end end + describe '#cross_project?' do + context 'when source and target repositories are different' do + let(:raw_data) { double(base_data.merge(head: forked_branch)) } + + it 'returns true' do + expect(pull_request.cross_project?).to eq true + end + end + + context 'when source and target repositories are the same' do + let(:raw_data) { double(base_data.merge(head: source_branch)) } + + it 'returns false' do + expect(pull_request.cross_project?).to eq false + end + end + end + describe '#url' do let(:raw_data) { double(base_data) } diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index dd5f7098d06..3ea62df62f2 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -647,7 +647,7 @@ describe Ci::Pipeline, models: true do let(:pipeline) { create(:ci_pipeline, status: :manual) } it 'returns detailed status for blocked pipeline' do - expect(subject.text).to eq 'manual' + expect(subject.text).to eq 'blocked' end end diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 16d5f2bf0b8..62740ec29fd 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -3,7 +3,7 @@ require 'capybara/rspec' require 'capybara/poltergeist' # Give CI some extra time -timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 90 : 10 +timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 30 : 10 Capybara.javascript_driver = :poltergeist Capybara.register_driver :poltergeist do |app| diff --git a/spec/support/filtered_search_helpers.rb b/spec/support/filtered_search_helpers.rb index f21b85ec10b..6b009b132b6 100644 --- a/spec/support/filtered_search_helpers.rb +++ b/spec/support/filtered_search_helpers.rb @@ -4,9 +4,14 @@ module FilteredSearchHelpers end # Enables input to be set (similar to copy and paste) - def input_filtered_search(search_term, submit: true) - # Add an extra space to engage visual tokens - filtered_search.set("#{search_term} ") + def input_filtered_search(search_term, submit: true, extra_space: true) + search = search_term + if extra_space + # Add an extra space to engage visual tokens + search = "#{search_term} " + end + + filtered_search.set(search) if submit filtered_search.send_keys(:enter) diff --git a/vendor/gitignore/Android.gitignore b/vendor/gitignore/Android.gitignore index a1a65c2d72e..520a86352f7 100644 --- a/vendor/gitignore/Android.gitignore +++ b/vendor/gitignore/Android.gitignore @@ -37,6 +37,7 @@ captures/ .idea/workspace.xml .idea/tasks.xml .idea/gradle.xml +.idea/dictionaries .idea/libraries # Keystore files @@ -48,7 +49,7 @@ captures/ # Google Services (e.g. APIs or Firebase) google-services.json -#Freeline +# Freeline freeline.py freeline/ freeline_project_description.json diff --git a/vendor/gitignore/Global/Eclipse.gitignore b/vendor/gitignore/Global/Eclipse.gitignore index 31c9fb31167..4f88399d2d8 100644 --- a/vendor/gitignore/Global/Eclipse.gitignore +++ b/vendor/gitignore/Global/Eclipse.gitignore @@ -49,3 +49,8 @@ local.properties # Code Recommenders .recommenders/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet diff --git a/vendor/gitignore/Global/JetBrains.gitignore b/vendor/gitignore/Global/JetBrains.gitignore index 401fee15748..ec7e95c6ab5 100644 --- a/vendor/gitignore/Global/JetBrains.gitignore +++ b/vendor/gitignore/Global/JetBrains.gitignore @@ -4,6 +4,7 @@ # User-specific stuff: .idea/**/workspace.xml .idea/**/tasks.xml +.idea/dictionaries # Sensitive or high-churn files: .idea/**/dataSources/ diff --git a/vendor/gitignore/Global/SBT.gitignore b/vendor/gitignore/Global/SBT.gitignore index 970d897c75c..5ed6acb6576 100644 --- a/vendor/gitignore/Global/SBT.gitignore +++ b/vendor/gitignore/Global/SBT.gitignore @@ -1,9 +1,12 @@ # Simple Build Tool # http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control +dist/* target/ lib_managed/ src_managed/ project/boot/ +project/plugins/project/ .history .cache +.lib/ diff --git a/vendor/gitignore/Java.gitignore b/vendor/gitignore/Java.gitignore index dbb4a2dfa1a..6143e53f9e3 100644 --- a/vendor/gitignore/Java.gitignore +++ b/vendor/gitignore/Java.gitignore @@ -1,3 +1,4 @@ +# Compiled class file *.class # Log file diff --git a/vendor/gitignore/Maven.gitignore b/vendor/gitignore/Maven.gitignore index 9af45b175ae..5f2dbe11df9 100644 --- a/vendor/gitignore/Maven.gitignore +++ b/vendor/gitignore/Maven.gitignore @@ -8,5 +8,5 @@ dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties -# Exclude maven wrapper +# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) !/.mvn/wrapper/maven-wrapper.jar diff --git a/vendor/gitignore/Node.gitignore b/vendor/gitignore/Node.gitignore index 38ac77e405e..00cbbdf53f6 100644 --- a/vendor/gitignore/Node.gitignore +++ b/vendor/gitignore/Node.gitignore @@ -2,6 +2,8 @@ logs *.log npm-debug.log* +yarn-debug.log* +yarn-error.log* # Runtime data pids diff --git a/vendor/gitignore/Objective-C.gitignore b/vendor/gitignore/Objective-C.gitignore index af90c007a3f..09dfede4814 100644 --- a/vendor/gitignore/Objective-C.gitignore +++ b/vendor/gitignore/Objective-C.gitignore @@ -45,10 +45,10 @@ Carthage/Build # fastlane # -# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the # screenshots whenever they are needed. # For more information about the recommended setup visit: -# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md +# https://docs.fastlane.tools/best-practices/source-control/#source-control fastlane/report.xml fastlane/Preview.html diff --git a/vendor/gitignore/PlayFramework.gitignore b/vendor/gitignore/PlayFramework.gitignore index 6d67f119175..ae5ec9fe1d9 100644 --- a/vendor/gitignore/PlayFramework.gitignore +++ b/vendor/gitignore/PlayFramework.gitignore @@ -5,6 +5,7 @@ bin/ /lib/ /logs/ /modules +/project/project /project/target /target tmp/ diff --git a/vendor/gitignore/Python.gitignore b/vendor/gitignore/Python.gitignore index cf3102d6b00..62c1e736924 100644 --- a/vendor/gitignore/Python.gitignore +++ b/vendor/gitignore/Python.gitignore @@ -76,6 +76,9 @@ target/ # celery beat schedule file celerybeat-schedule +# SageMath parsed files +*.sage.py + # dotenv .env diff --git a/vendor/gitignore/Scala.gitignore b/vendor/gitignore/Scala.gitignore index 006a7b247fe..9c07d4ae988 100644 --- a/vendor/gitignore/Scala.gitignore +++ b/vendor/gitignore/Scala.gitignore @@ -1,23 +1,2 @@ *.class *.log - -# sbt specific -.cache -.history -.lib/ -dist/* -target/ -lib_managed/ -src_managed/ -project/boot/ -project/plugins/project/ - -# Scala-IDE specific -.ensime -.ensime_cache/ -.scala_dependencies -.worksheet - -# ENSIME specific -.ensime_cache/ -.ensime diff --git a/vendor/gitignore/Swift.gitignore b/vendor/gitignore/Swift.gitignore index 099d22ae2f4..d5340449396 100644 --- a/vendor/gitignore/Swift.gitignore +++ b/vendor/gitignore/Swift.gitignore @@ -59,7 +59,7 @@ Carthage/Build # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the # screenshots whenever they are needed. # For more information about the recommended setup visit: -# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md +# https://docs.fastlane.tools/best-practices/source-control/#source-control fastlane/report.xml fastlane/Preview.html diff --git a/vendor/gitignore/Symfony.gitignore b/vendor/gitignore/Symfony.gitignore index ed4d3c6c28d..6c224e024e9 100644 --- a/vendor/gitignore/Symfony.gitignore +++ b/vendor/gitignore/Symfony.gitignore @@ -25,7 +25,6 @@ /bin/* !bin/console !bin/symfony_requirements -/vendor/ # Assets and user uploads /web/bundles/ @@ -38,8 +37,5 @@ # Build data /build/ -# Composer PHAR -/composer.phar - # Backup entities generated with doctrine:generate:entities command **/Entity/*~ diff --git a/vendor/gitignore/TeX.gitignore b/vendor/gitignore/TeX.gitignore index 69bfb1eec3e..57ed9f5d972 100644 --- a/vendor/gitignore/TeX.gitignore +++ b/vendor/gitignore/TeX.gitignore @@ -28,7 +28,6 @@ *.blg *-blx.aux *-blx.bib -*.brf *.run.xml ## Build tool auxiliary files: @@ -77,8 +76,6 @@ acs-*.bib *.t[1-9] *.t[1-9][0-9] *.tfm -*.[1-9] -*.[1-9][0-9] #(r)(e)ledmac/(r)(e)ledpar *.end @@ -134,6 +131,9 @@ acs-*.bib *.mlf *.mlt *.mtc[0-9]* +*.slf[0-9]* +*.slt[0-9]* +*.stc[0-9]* # minted _minted* @@ -142,9 +142,6 @@ _minted* # morewrites *.mw -# mylatexformat -*.fmt - # nomencl *.nlo diff --git a/vendor/gitignore/VisualStudio.gitignore b/vendor/gitignore/VisualStudio.gitignore index 8054980d742..a752eacca7d 100644 --- a/vendor/gitignore/VisualStudio.gitignore +++ b/vendor/gitignore/VisualStudio.gitignore @@ -166,7 +166,7 @@ PublishScripts/ !**/packages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files +# NuGet v3's project.json files produces more ignorable files *.nuget.props *.nuget.targets @@ -276,3 +276,12 @@ __pycache__/ # Cake - Uncomment if you are using it # tools/** # !tools/packages.config + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs
\ No newline at end of file diff --git a/vendor/gitlab-ci-yml/Android.gitlab-ci.yml b/vendor/gitlab-ci-yml/Android.gitlab-ci.yml new file mode 100644 index 00000000000..5f9d54ff574 --- /dev/null +++ b/vendor/gitlab-ci-yml/Android.gitlab-ci.yml @@ -0,0 +1,51 @@ +# Read more about this script on this blog post https://about.gitlab.com/2016/11/30/setting-up-gitlab-ci-for-android-projects/, by Greyson Parrelli +image: openjdk:8-jdk + +variables: + ANDROID_COMPILE_SDK: "25" + ANDROID_BUILD_TOOLS: "24.0.0" + ANDROID_SDK_TOOLS: "24.4.1" + +before_script: + - apt-get --quiet update --yes + - apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1 + - wget --quiet --output-document=android-sdk.tgz https://dl.google.com/android/android-sdk_r${ANDROID_SDK_TOOLS}-linux.tgz + - tar --extract --gzip --file=android-sdk.tgz + - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter android-${ANDROID_COMPILE_SDK} + - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter platform-tools + - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter build-tools-${ANDROID_BUILD_TOOLS} + - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-android-m2repository + - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-google_play_services + - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-m2repository + - export ANDROID_HOME=$PWD/android-sdk-linux + - export PATH=$PATH:$PWD/android-sdk-linux/platform-tools/ + - chmod +x ./gradlew + +stages: + - build + - test + +build: + stage: build + script: + - ./gradlew assembleDebug + artifacts: + paths: + - app/build/outputs/ + +unitTests: + stage: test + script: + - ./gradlew test + +functionalTests: + stage: test + script: + - wget --quiet --output-document=android-wait-for-emulator https://raw.githubusercontent.com/travis-ci/travis-cookbooks/0f497eb71291b52a703143c5cd63a217c8766dc9/community-cookbooks/android-sdk/files/default/android-wait-for-emulator + - chmod +x android-wait-for-emulator + - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter sys-img-x86-google_apis-${ANDROID_COMPILE_SDK} + - echo no | android-sdk-linux/tools/android create avd -n test -t android-${ANDROID_COMPILE_SDK} --abi google_apis/x86 + - android-sdk-linux/tools/emulator64-x86 -avd test -no-window -no-audio & + - ./android-wait-for-emulator + - adb shell input keyevent 82 + - ./gradlew cAT diff --git a/vendor/gitlab-ci-yml/Bash.gitlab-ci.yml b/vendor/gitlab-ci-yml/Bash.gitlab-ci.yml new file mode 100644 index 00000000000..27537689b80 --- /dev/null +++ b/vendor/gitlab-ci-yml/Bash.gitlab-ci.yml @@ -0,0 +1,35 @@ +# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options + +# you can delete this line if you're not using Docker +image: busybox:latest + +before_script: + - echo "Before script section" + - echo "For example you might run an update here or install a build dependency" + - echo "Or perhaps you might print out some debugging details" + +after_script: + - echo "After script section" + - echo "For example you might do some cleanup here" + +build1: + stage: build + script: + - echo "Do your build here" + +test1: + stage: test + script: + - echo "Do a test here" + - echo "For example run a test suite" + +test2: + stage: test + script: + - echo "Do another parallel test here" + - echo "For example run a lint test" + +deploy1: + stage: deploy + script: + - echo "Do your deploy here"
\ No newline at end of file diff --git a/vendor/gitlab-ci-yml/Crystal.gitlab-ci.yml b/vendor/gitlab-ci-yml/Crystal.gitlab-ci.yml index e8da49a935e..37e44735f7c 100644 --- a/vendor/gitlab-ci-yml/Crystal.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/Crystal.gitlab-ci.yml @@ -1,4 +1,3 @@ -# This file is a template, and might need editing before it works on your project. # Official language image. Look for the different tagged releases at: # https://hub.docker.com/r/crystallang/crystal/ image: "crystallang/crystal:latest" diff --git a/vendor/gitlab-ci-yml/Django.gitlab-ci.yml b/vendor/gitlab-ci-yml/Django.gitlab-ci.yml new file mode 100644 index 00000000000..b3106863cca --- /dev/null +++ b/vendor/gitlab-ci-yml/Django.gitlab-ci.yml @@ -0,0 +1,34 @@ +# Official framework image. Look for the different tagged releases at: +# https://hub.docker.com/r/library/python +image: python:latest + +# Pick zero or more services to be used on all builds. +# Only needed when using a docker container to run your tests in. +# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-service +services: + - mysql:latest + - postgres:latest + +variables: + POSTGRES_DB: database_name + +# This folder is cached between builds +# http://docs.gitlab.com/ce/ci/yaml/README.html#cache +cache: + paths: + - ~/.cache/pip/ + +# This is a basic example for a gem or script which doesn't use +# services such as redis or postgres +before_script: + - python -V # Print out python version for debugging + # Uncomment next line if your Django app needs a JS runtime: + # - apt-get update -q && apt-get install nodejs -yqq + - pip install -r requirements.txt + +test: + variables: + DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/$POSTGRES_DB" + script: + - python manage.py migrate + - python manage.py test diff --git a/vendor/gitlab-ci-yml/Gradle.gitlab-ci.yml b/vendor/gitlab-ci-yml/Gradle.gitlab-ci.yml index 98d3039ad06..a65e48a3389 100644 --- a/vendor/gitlab-ci-yml/Gradle.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/Gradle.gitlab-ci.yml @@ -6,6 +6,13 @@ # https://github.com/gradle/gradle image: java:8 +# Disable the Gradle daemon for Continuous Integration servers as correctness +# is usually a priority over speed in CI environments. Using a fresh +# runtime for each build is more reliable since the runtime is completely +# isolated from any previous builds. +variables: + GRADLE_OPTS: "-Dorg.gradle.daemon=false" + # Make the gradle wrapper executable. This essentially downloads a copy of # Gradle to build the project with. # https://docs.gradle.org/current/userguide/gradle_wrapper.html diff --git a/vendor/gitlab-ci-yml/LICENSE b/vendor/gitlab-ci-yml/LICENSE index 80f7b87b6c0..d6c93c6fcf7 100644 --- a/vendor/gitlab-ci-yml/LICENSE +++ b/vendor/gitlab-ci-yml/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 GitLab.org +Copyright (c) 2016-2017 GitLab.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/gitlab-ci-yml/Laravel.gitlab-ci.yml b/vendor/gitlab-ci-yml/Laravel.gitlab-ci.yml new file mode 100644 index 00000000000..0d6a6eddc97 --- /dev/null +++ b/vendor/gitlab-ci-yml/Laravel.gitlab-ci.yml @@ -0,0 +1,78 @@ +# Official framework image. Look for the different tagged releases at: +# https://hub.docker.com/r/library/php +image: php:latest + +# Pick zero or more services to be used on all builds. +# Only needed when using a docker container to run your tests in. +# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-service +services: + - mysql:latest + +variables: + MYSQL_DATABASE: project_name + MYSQL_ROOT_PASSWORD: secret + +# This folder is cached between builds +# http://docs.gitlab.com/ce/ci/yaml/README.html#cache +cache: + paths: + - vendor/ + - node_modules/ + +# This is a basic example for a gem or script which doesn't use +# services such as redis or postgres +before_script: + # Update packages + - apt-get update -yqq + + # Upgrade to Node 7 + - curl -sL https://deb.nodesource.com/setup_7.x | bash - + + # Install dependencies + - apt-get install git nodejs libcurl4-gnutls-dev libicu-dev libmcrypt-dev libvpx-dev libjpeg-dev libpng-dev libxpm-dev zlib1g-dev libfreetype6-dev libxml2-dev libexpat1-dev libbz2-dev libgmp3-dev libldap2-dev unixodbc-dev libpq-dev libsqlite3-dev libaspell-dev libsnmp-dev libpcre3-dev libtidy-dev -yqq + + # Install php extensions + - docker-php-ext-install mbstring mcrypt pdo_mysql curl json intl gd xml zip bz2 opcache + + # Install Composer and project dependencies. + - curl -sS https://getcomposer.org/installer | php + - php composer.phar install + + # Install Node dependencies. + # comment this out if you don't have a node dependency + - npm install + + # Copy over testing configuration. + # Don't forget to set the database config in .env.testing correctly + # DB_HOST=mysql + # DB_DATABASE=project_name + # DB_USERNAME=root + # DB_PASSWORD=secret + - cp .env.testing .env + + # Run npm build + # comment this out if you don't have a frontend build + # you can change this to to your frontend building script like + # npm run build + - npm run dev + + # Generate an application key. Re-cache. + - php artisan key:generate + - php artisan config:cache + + # Run database migrations. + - php artisan migrate + + # Run database seed + - php artisan db:seed + +test: + script: + # run laravel tests + - php vendor/bin/phpunit --coverage-text --colors=never + + # run frontend tests + # if you have any task for testing frontend + # set it in your package.json script + # comment this out if you don't have a frontend test + - npm test diff --git a/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml b/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml index 1678a47f9ac..b75f0665bee 100644 --- a/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml @@ -17,16 +17,17 @@ variables: # This will supress any download for dependencies and plugins or upload messages which would clutter the console log. # `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work. - MAVEN_OPTS: "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" + MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" # As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used # when running from the command line. # `installAtEnd` and `deployAtEnd`are only effective with recent version of the corresponding plugins. MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true" # Cache downloaded dependencies and plugins between builds. +# To keep cache across branches add 'key: "$CI_BUILD_REF_NAME"' cache: paths: - - /root/.m2/repository/ + - .m2/repository # This will only validate and compile stuff and run e.g. maven-enforcer-plugin. # Because some enforcer rules might check dependency convergence and class duplications diff --git a/vendor/gitlab-ci-yml/Openshift.gitlab-ci.yml b/vendor/gitlab-ci-yml/OpenShift.gitlab-ci.yml index 2ba5cad9682..6b6c405a507 100644 --- a/vendor/gitlab-ci-yml/Openshift.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/OpenShift.gitlab-ci.yml @@ -1,4 +1,3 @@ -# This file is a template, and might need editing before it works on your project. image: ayufan/openshift-cli stages: @@ -6,6 +5,7 @@ stages: - review - staging - production + - cleanup variables: OPENSHIFT_SERVER: openshift.default.svc.cluster.local @@ -28,7 +28,7 @@ test2: .deploy: &deploy before_script: - oc login "$OPENSHIFT_SERVER" --token="$OPENSHIFT_TOKEN" --insecure-skip-tls-verify - - oc project "$CI_PROJECT_NAME" 2> /dev/null || oc new-project "$CI_PROJECT_NAME" + - oc project "$CI_PROJECT_NAME-$CI_PROJECT_ID" 2> /dev/null || oc new-project "$CI_PROJECT_NAME-$CI_PROJECT_ID" script: - "oc get services $APP 2> /dev/null || oc new-app . --name=$APP --strategy=docker" - "oc start-build $APP --from-dir=. --follow || sleep 3s || oc start-build $APP --from-dir=. --follow" @@ -51,7 +51,7 @@ review: stop-review: <<: *deploy - stage: review + stage: cleanup script: - oc delete all -l "app=$APP" when: manual diff --git a/vendor/gitlab-ci-yml/PHP.gitlab-ci.yml b/vendor/gitlab-ci-yml/PHP.gitlab-ci.yml new file mode 100644 index 00000000000..bb8caa49d6b --- /dev/null +++ b/vendor/gitlab-ci-yml/PHP.gitlab-ci.yml @@ -0,0 +1,33 @@ +# Select image from https://hub.docker.com/_/php/ +image: php:7.1.1 + +# Select what we should cache between builds +cache: + paths: + - vendor/ + +before_script: +- apt-get update -yqq +- apt-get install -yqq git libmcrypt-dev libpq-dev libcurl4-gnutls-dev libicu-dev libvpx-dev libjpeg-dev libpng-dev libxpm-dev zlib1g-dev libfreetype6-dev libxml2-dev libexpat1-dev libbz2-dev libgmp3-dev libldap2-dev unixodbc-dev libsqlite3-dev libaspell-dev libsnmp-dev libpcre3-dev libtidy-dev +# Install PHP extensions +- docker-php-ext-install mbstring mcrypt pdo_pgsql curl json intl gd xml zip bz2 opcache +# Install and run Composer +- curl -sS https://getcomposer.org/installer | php +- php composer.phar install + +# Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service +# See http://docs.gitlab.com/ce/ci/services/README.html for examples. +services: + - mysql:5.7 + +# Set any variables we need +variables: + # Configure mysql environment variables (https://hub.docker.com/r/_/mysql/) + MYSQL_DATABASE: mysql_database + MYSQL_ROOT_PASSWORD: mysql_strong_password + +# Run our tests +# If Xdebug was installed you can generate a coverage report and see code coverage metrics. +test: + script: + - vendor/bin/phpunit --configuration phpunit.xml --coverage-text --colors=never
\ No newline at end of file diff --git a/vendor/gitlab-ci-yml/Pages/Hugo.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/Hugo.gitlab-ci.yml index 45df6975259..a72b8281401 100644 --- a/vendor/gitlab-ci-yml/Pages/Hugo.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/Pages/Hugo.gitlab-ci.yml @@ -9,3 +9,9 @@ pages: - public only: - master + +test: + script: + - hugo + except: + - master diff --git a/vendor/gitlab-ci-yml/Pages/Jekyll.gitlab-ci.yml b/vendor/gitlab-ci-yml/Pages/Jekyll.gitlab-ci.yml index 36918fc005a..d98cf94d635 100644 --- a/vendor/gitlab-ci-yml/Pages/Jekyll.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/Pages/Jekyll.gitlab-ci.yml @@ -1,11 +1,15 @@ -# Full project: https://gitlab.com/pages/jekyll +# Template project: https://gitlab.com/pages/jekyll +# Docs: https://docs.gitlab.com/ce/pages/ +# Jekyll version: 3.4.0 image: ruby:2.3 +before_script: +- bundle install + test: stage: test script: - - gem install jekyll - - jekyll build -d test + - bundle exec jekyll build -d test artifacts: paths: - test @@ -15,10 +19,10 @@ test: pages: stage: deploy script: - - gem install jekyll - - jekyll build -d public + - bundle exec jekyll build -d public artifacts: paths: - public only: - master +
\ No newline at end of file diff --git a/vendor/gitlab-ci-yml/autodeploy/Kubernetes.gitlab-ci.yml b/vendor/gitlab-ci-yml/autodeploy/Kubernetes.gitlab-ci.yml index 7298ea73bab..574f9365f14 100644 --- a/vendor/gitlab-ci-yml/autodeploy/Kubernetes.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/autodeploy/Kubernetes.gitlab-ci.yml @@ -12,6 +12,7 @@ stages: - review - staging - production + - cleanup build: stage: build @@ -61,7 +62,7 @@ review: - master stop_review: - stage: review + stage: cleanup variables: GIT_STRATEGY: none script: diff --git a/vendor/gitlab-ci-yml/autodeploy/OpenShift.gitlab-ci.yml b/vendor/gitlab-ci-yml/autodeploy/OpenShift.gitlab-ci.yml index 249adbc9f4a..4d6f4e00ebb 100644 --- a/vendor/gitlab-ci-yml/autodeploy/OpenShift.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/autodeploy/OpenShift.gitlab-ci.yml @@ -12,6 +12,7 @@ stages: - review - staging - production + - cleanup build: stage: build @@ -61,7 +62,7 @@ review: - master stop_review: - stage: review + stage: cleanup variables: GIT_STRATEGY: none script: |