Commit 62ded594 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-07-18

# Conflicts:
#	app/assets/stylesheets/framework/variables.scss
#	locale/gitlab.pot

[ci skip]
parents f76828db 9bdc9b1a
......@@ -85,6 +85,9 @@ export default {
}
return __('Show latest version');
},
canCurrentUserFork() {
return this.currentUser.canFork === true && this.currentUser.canCreateMergeRequest;
},
},
watch: {
diffViewType() {
......@@ -192,7 +195,7 @@ export default {
v-for="file in diffFiles"
:key="file.newPath"
:file="file"
:current-user="currentUser"
:can-current-user-fork="canCurrentUserFork"
/>
</div>
<no-changes v-else />
......
......@@ -18,8 +18,8 @@ export default {
type: Object,
required: true,
},
currentUser: {
type: Object,
canCurrentUserFork: {
type: Boolean,
required: true,
},
},
......@@ -87,7 +87,7 @@ export default {
class="diff-file file-holder"
>
<diff-file-header
:current-user="currentUser"
:can-current-user-fork="canCurrentUserFork"
:diff-file="file"
:collapsible="true"
:expanded="!isCollapsed"
......
......@@ -39,8 +39,8 @@ export default {
required: false,
default: true,
},
currentUser: {
type: Object,
canCurrentUserFork: {
type: Boolean,
required: true,
},
},
......@@ -228,7 +228,7 @@ export default {
<edit-button
v-if="!diffFile.deletedFile"
:current-user="currentUser"
:can-current-user-fork="canCurrentUserFork"
:edit-path="diffFile.editPath"
:can-modify-blob="diffFile.canModifyBlob"
@showForkMessage="showForkMessage"
......
......@@ -13,12 +13,8 @@ export default {
noteForm,
},
props: {
diffFile: {
type: Object,
required: true,
},
diffLines: {
type: Array,
diffFileHash: {
type: String,
required: true,
},
line: {
......@@ -40,6 +36,7 @@ export default {
noteableData: state => state.notes.noteableData,
diffViewType: state => state.diffs.diffViewType,
}),
...mapGetters('diffs', ['getDiffFileByHash']),
...mapGetters(['isLoggedIn', 'noteableType', 'getNoteableData', 'getNotesDataByProp']),
},
mounted() {
......@@ -68,13 +65,14 @@ export default {
});
},
handleSaveNote(note) {
const selectedDiffFile = this.getDiffFileByHash(this.diffFileHash);
const postData = getNoteFormData({
note,
noteableData: this.noteableData,
noteableType: this.noteableType,
noteTargetLine: this.noteTargetLine,
diffViewType: this.diffViewType,
diffFile: this.diffFile,
diffFile: selectedDiffFile,
linePosition: this.position,
});
......
......@@ -24,8 +24,12 @@ export default {
type: Object,
required: true,
},
diffFile: {
type: Object,
fileHash: {
type: String,
required: true,
},
contextLinesPath: {
type: String,
required: true,
},
diffViewType: {
......@@ -120,14 +124,14 @@ export default {
:class="classNameMap"
>
<diff-line-gutter-content
:file-hash="diffFile.fileHash"
:file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line-type="normalizedLine.type"
:line-code="normalizedLine.lineCode"
:line-position="linePosition"
:line-number="lineNumber"
:meta-data="normalizedLine.metaData"
:show-comment-button="showCommentButton"
:context-lines-path="diffFile.contextLinesPath"
:is-bottom="isBottom"
:is-match-line="isMatchLine"
:is-context-line="isContentLine"
......
......@@ -5,8 +5,8 @@ export default {
type: String,
required: true,
},
currentUser: {
type: Object,
canCurrentUserFork: {
type: Boolean,
required: true,
},
canModifyBlob: {
......@@ -17,12 +17,12 @@ export default {
},
methods: {
handleEditClick(evt) {
if (!this.currentUser || this.canModifyBlob) {
if (!this.canCurrentUserFork || this.canModifyBlob) {
// if we can Edit, do default Edit button behavior
return;
}
if (this.currentUser.canFork && this.currentUser.canCreateMergeRequest) {
if (this.canCurrentUserFork) {
evt.preventDefault();
this.$emit('showForkMessage');
}
......
......@@ -13,12 +13,8 @@ export default {
type: Object,
required: true,
},
diffFile: {
type: Object,
required: true,
},
diffLines: {
type: Array,
diffFileHash: {
type: String,
required: true,
},
lineIndex: {
......@@ -58,10 +54,9 @@ export default {
/>
<diff-line-note-form
v-if="diffLineCommentForms[line.lineCode]"
:diff-file="diffFile"
:diff-lines="diffLines"
:diff-file-hash="diffFileHash"
:line="line"
:note-target-line="diffLines[lineIndex]"
:note-target-line="line"
/>
</div>
</td>
......
......@@ -16,8 +16,12 @@ export default {
DiffTableCell,
},
props: {
diffFile: {
type: Object,
fileHash: {
type: String,
required: true,
},
contextLinesPath: {
type: String,
required: true,
},
line: {
......@@ -50,7 +54,7 @@ export default {
inlineRowId() {
const { lineCode, oldLine, newLine } = this.line;
return lineCode || `${this.diffFile.fileHash}_${oldLine}_${newLine}`;
return lineCode || `${this.fileHash}_${oldLine}_${newLine}`;
},
},
created() {
......@@ -78,7 +82,8 @@ export default {
@mouseout="handleMouseMove"
>
<diff-table-cell
:diff-file="diffFile"
:file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line"
:line-type="oldLineType"
:is-bottom="isBottom"
......@@ -87,7 +92,8 @@ export default {
class="diff-line-num old_line"
/>
<diff-table-cell
:diff-file="diffFile"
:file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line"
:line-type="newLineType"
:is-bottom="isBottom"
......
......@@ -60,15 +60,15 @@ export default {
v-for="(line, index) in normalizedDiffLines"
>
<inline-diff-table-row
:diff-file="diffFile"
:file-hash="diffFile.fileHash"
:context-lines-path="diffFile.contextLinesPath"
:line="line"
:is-bottom="index + 1 === diffLinesLength"
:key="line.lineCode"
/>
<inline-diff-comment-row
v-if="shouldRenderCommentRow(line)"
:diff-file="diffFile"
:diff-lines="normalizedDiffLines"
:diff-file-hash="diffFile.fileHash"
:line="line"
:line-index="index"
:key="index"
......
......@@ -13,12 +13,8 @@ export default {
type: Object,
required: true,
},
diffFile: {
type: Object,
required: true,
},
diffLines: {
type: Array,
diffFileHash: {
type: String,
required: true,
},
lineIndex: {
......@@ -91,10 +87,9 @@ export default {
<diff-line-note-form
v-if="diffLineCommentForms[leftLineCode] &&
diffLineCommentForms[leftLineCode]"
:diff-file="diffFile"
:diff-lines="diffLines"
:diff-file-hash="diffFileHash"
:line="line.left"
:note-target-line="diffLines[lineIndex].left"
:note-target-line="line.left"
position="left"
/>
</td>
......@@ -112,10 +107,9 @@ export default {
<diff-line-note-form
v-if="diffLineCommentForms[rightLineCode] &&
diffLineCommentForms[rightLineCode] && line.right.type"
:diff-file="diffFile"
:diff-lines="diffLines"
:diff-file-hash="diffFileHash"
:line="line.right"
:note-target-line="diffLines[lineIndex].right"
:note-target-line="line.right"
position="right"
/>
</td>
......
......@@ -19,8 +19,12 @@ export default {
DiffTableCell,
},
props: {
diffFile: {
type: Object,
fileHash: {
type: String,
required: true,
},
contextLinesPath: {
type: String,
required: true,
},
line: {
......@@ -103,7 +107,8 @@ export default {
@mouseout="handleMouseMove"
>
<diff-table-cell
:diff-file="diffFile"
:file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line"
:line-type="oldLineType"
:line-position="linePositionLeft"
......@@ -123,7 +128,8 @@ export default {
>
</td>
<diff-table-cell
:diff-file="diffFile"
:file-hash="fileHash"
:context-lines-path="contextLinesPath"
:line="line"
:line-type="newLineType"
:line-position="linePositionRight"
......
......@@ -93,17 +93,17 @@ export default {
v-for="(line, index) in parallelDiffLines"
>
<parallel-diff-table-row
:diff-file="diffFile"
:file-hash="diffFile.fileHash"
:context-lines-path="diffFile.contextLinesPath"
:line="line"
:is-bottom="index + 1 === diffLinesLength"
:key="index"
/>
<parallel-diff-comment-row
v-if="shouldRenderCommentRow(line)"
:key="line.left.lineCode || line.right.lineCode"
:key="`dcr-${index}`"
:line="line"
:diff-file="diffFile"
:diff-lines="parallelDiffLines"
:diff-file-hash="diffFile.fileHash"
:line-index="index"
/>
</template>
......
......@@ -57,4 +57,8 @@ export const getDiffFileDiscussions = (state, getters, rootState, rootGetters) =
) || [];
// prevent babel-plugin-rewire from generating an invalid default during karma∂ tests
export const getDiffFileByHash = state => fileHash =>
state.diffFiles.find(file => file.fileHash === fileHash);
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
......@@ -38,6 +38,7 @@ export default {
<button
:aria-label="label"
type="button"
class="btn-blank"
@click.stop.prevent="clicked"
>
<icon
......
import _ from 'underscore';
function sortMetrics(metrics) {
return _.chain(metrics).sortBy('title').sortBy('weight').value();
return _.chain(metrics)
.sortBy('title')
.sortBy('weight')
.value();
}
function normalizeMetrics(metrics) {
......@@ -39,7 +42,9 @@ export default class MonitoringStore {
}
storeEnvironmentsData(environmentsData = []) {
this.environmentsData = environmentsData;
this.environmentsData = environmentsData.filter(
environment => !!environment.latest.last_deployment,
);
}
getMetricsCount() {
......
<script>
import { mapState, mapActions } from 'vuex';
import imageDiffHelper from '~/image_diff/helpers/index';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
import { trimFirstCharOfLineContent } from '~/diffs/store/utils';
import { mapState, mapActions } from 'vuex';
import imageDiffHelper from '~/image_diff/helpers/index';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
import { trimFirstCharOfLineContent } from '~/diffs/store/utils';
export default {
components: {
DiffFileHeader,
SkeletonLoadingContainer,
export default {
components: {
DiffFileHeader,
SkeletonLoadingContainer,
},
props: {
discussion: {
type: Object,
required: true,
},
props: {
discussion: {
type: Object,
required: true,
},
},
data() {
return {
error: false,
};
},
computed: {
...mapState({
noteableData: state => state.notes.noteableData,
}),
hasTruncatedDiffLines() {
return this.discussion.truncatedDiffLines && this.discussion.truncatedDiffLines.length !== 0;
},
data() {
return {
error: false,
};
isDiscussionsExpanded() {
return true; // TODO: @fatihacet - Fix this.
},
computed: {
...mapState({
noteableData: state => state.notes.noteableData,
}),
hasTruncatedDiffLines() {
return this.discussion.truncatedDiffLines &&
this.discussion.truncatedDiffLines.length !== 0;
},
isDiscussionsExpanded() {
return true; // TODO: @fatihacet - Fix this.
},
isCollapsed() {
return this.diffFile.collapsed || false;
},
isImageDiff() {
return !this.diffFile.text;
},
diffFileClass() {
const { text } = this.diffFile;
return text ? 'text-file' : 'js-image-file';
},
diffFile() {
return convertObjectPropsToCamelCase(this.discussion.diffFile, { deep: true });
},
imageDiffHtml() {
return this.discussion.imageDiffHtml;
},
currentUser() {
return this.noteableData.current_user;
},
userColorScheme() {
return window.gon.user_color_scheme;
},
normalizedDiffLines() {
if (this.discussion.truncatedDiffLines) {
return this.discussion.truncatedDiffLines.map(line =>
trimFirstCharOfLineContent(convertObjectPropsToCamelCase(line)),
);
}
return [];
},
isCollapsed() {
return this.diffFile.collapsed || false;
},
isImageDiff() {
return !this.diffFile.text;
},
diffFileClass() {
const { text } = this.diffFile;
return text ? 'text-file' : 'js-image-file';
},
diffFile() {
return convertObjectPropsToCamelCase(this.discussion.diffFile, { deep: true });
},
mounted() {
if (this.isImageDiff) {
const canCreateNote = false;
const renderCommentBadge = true;
imageDiffHelper.initImageDiff(this.$refs.fileHolder, canCreateNote, renderCommentBadge);
} else if (!this.hasTruncatedDiffLines) {
this.fetchDiff();
imageDiffHtml() {
return this.discussion.imageDiffHtml;
},
userColorScheme() {
return window.gon.user_color_scheme;
},
normalizedDiffLines() {
if (this.discussion.truncatedDiffLines) {
return this.discussion.truncatedDiffLines.map(line =>
trimFirstCharOfLineContent(convertObjectPropsToCamelCase(line)),
);
}
return [];
},
},
mounted() {
if (this.isImageDiff) {
const canCreateNote = false;
const renderCommentBadge = true;
imageDiffHelper.initImageDiff(this.$refs.fileHolder, canCreateNote, renderCommentBadge);
} else if (!this.hasTruncatedDiffLines) {
this.fetchDiff();
}
},
methods: {
...mapActions(['fetchDiscussionDiffLines']),
rowTag(html) {
return html.outerHTML ? 'tr' : 'template';
},
methods: {
...mapActions(['fetchDiscussionDiffLines']),
rowTag(html) {
return html.outerHTML ? 'tr' : 'template';
},
fetchDiff() {
this.error = false;
this.fetchDiscussionDiffLines(this.discussion)
.then(this.highlight)
.catch(() => {
this.error = true;
});
},
fetchDiff() {
this.error = false;
this.fetchDiscussionDiffLines(this.discussion)
.then(this.highlight)
.catch(() => {
this.error = true;
});
},
};
},
};
</script>
<template>
......@@ -99,7 +95,7 @@
>
<diff-file-header
:diff-file="diffFile"
:current-user="currentUser"
:can-current-user-fork="false"
:discussions-expanded="isDiscussionsExpanded"
:expanded="!isCollapsed"
/>
......
......@@ -302,10 +302,13 @@ $system-footer-height: $system-header-height;
$flash-height: 52px;
$context-header-height: 60px;
$breadcrumb-min-height: 48px;
<<<<<<< HEAD
$issue-box-upcoming-bg: #8f8f8f;
$pages-group-name-color: #4c4e54;
$ldap-members-override-bg: $orange-50;
=======
>>>>>>> upstream/master
/*
* Common component specific colors
......
......@@ -551,6 +551,7 @@
@include media-breakpoint-up(lg) {
.branch-actions {
align-self: center;
margin-left: $gl-padding;
}
}
}
......
......@@ -210,7 +210,7 @@ class Note < ActiveRecord::Base
end
def hook_attrs
attributes
Gitlab::HookData::NoteBuilder.new(self).build
end
def for_commit?
......
......@@ -60,7 +60,7 @@ class WikiPage
attr_accessor :attributes
def hook_attrs
attributes
Gitlab::HookData::WikiPageBuilder.new(self).build
end
def initialize(wiki, page = nil, persisted = false)
......
# frozen_string_literal: true
module ApplicationSettings
class BaseService < ::BaseService
def initialize(application_setting, user, params = {})
......
# frozen_string_literal: true
module ApplicationSettings
class UpdateService < ApplicationSettings::BaseService
prepend EE::ApplicationSettings::UpdateService
......
# frozen_string_literal: true
module Applications
class CreateService
prepend ::EE::Applications::CreateService
......
# frozen_string_literal: true
module Auth
class ContainerRegistryAuthenticationService < BaseService
AUDIENCE = 'container_registry'.freeze
......
# frozen_string_literal: true
module Badges
class BaseService
protected
......
# frozen_string_literal: true
module Badges
class BuildService < Badges::BaseService
# returns the created badge
......
# frozen_string_literal: true
module Badges
class CreateService < Badges::BaseService
# returns the created badge
......
# frozen_string_literal: true
module Badges
class UpdateService < Badges::BaseService
# returns the updated badge
......
# frozen_string_literal: true
module Boards
class BaseService < ::BaseService
prepend EE::Boards::BaseService
......
# frozen_string_literal: true
module Boards
class CreateService < Boards::BaseService
prepend EE::Boards::CreateService
......
# frozen_string_literal: true
module Boards
module Issues
class CreateService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Issues
class ListService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Issues
class MoveService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
class ListService < Boards::BaseService
prepend EE::Boards::ListService
......
# frozen_string_literal: true
module Boards
module Lists
class CreateService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Lists
class DestroyService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Lists
class GenerateService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Lists
class ListService < Boards::BaseService
......
# frozen_string_literal: true
module Boards
module Lists
class MoveService < Boards::BaseService
......
# frozen_string_literal: true
module ChatNames
class AuthorizeUserService
include Gitlab::Routing
......
# frozen_string_literal: true
module ChatNames
class FindUserService
def initialize(service, params)
......
# frozen_string_literal: true
module Ci
class CreatePipelineScheduleService < BaseService
def execute
......
# frozen_string_literal: true
module Ci
class CreatePipelineService < BaseService
attr_reader :pipeline
......
# frozen_string_literal: true
module Ci
##
# We call this service everytime we persist a CI/CD job.
......
# frozen_string_literal: true
module Ci
class ExtractSectionsFromBuildTraceService < BaseService
def execute(build)
......
# frozen_string_literal: true
##
# TODO:
# Almost components in this class were copied from app/models/project_services/kubernetes_service.rb
......
# frozen_string_literal: true
module Ci
class PipelineTriggerService < BaseService
include Gitlab::Utils::StrongMemoize
......
# frozen_string_literal: true
module Ci
class PlayBuildService < ::BaseService
def execute(build)
......
# frozen_string_literal: true
module Ci
class ProcessPipelineService < BaseService
attr_reader :pipeline
......
# frozen_string_literal: true
module Ci
# This class responsible for assigning
# proper pending build to runner on runner API request
......
# frozen_string_literal: true
module Ci
class RetryBuildService < ::BaseService
CLONE_ACCESSORS = %i[pipeline project ref tag options commands name
......
# frozen_string_literal: true
module Ci
class RetryPipelineService < ::BaseService
include Gitlab::OptimisticLocking
......
# frozen_string_literal: true
module Ci
class StopEnvironmentsService < BaseService
attr_reader :ref
......
# frozen_string_literal: true
module Ci
class UpdateBuildQueueService
def execute(build)
......
# frozen_string_literal: true
module Ci
class UpdateRunnerService
attr_reader :runner
......
# frozen_string_literal: true
module Clusters
module Applications
class BaseHelmService
......
# frozen_string_literal: true
module Clusters
module Applications
class CheckIngressIpAddressService < BaseHelmService
......
# frozen_string_literal: true
module Clusters
module Applications
class CheckInstallationProgressService < BaseHelmService
......
# frozen_string_literal: true
module Clusters
module Applications
class InstallService < BaseHelmService
......
# frozen_string_literal: true
module Clusters
module Applications
class ScheduleInstallationService < ::BaseService
......
# frozen_string_literal: true
module Clusters
class CreateService < BaseService
prepend EE::Clusters::CreateService
......
# frozen_string_literal: true
module Clusters
module Gcp
class FetchOperationService
......
# frozen_string_literal: true
module Clusters
module Gcp
class FinalizeCreationService
......
# frozen_string_literal: true
module Clusters
module Gcp
class ProvisionService
......
# frozen_string_literal: true
module Clusters
module Gcp
class VerifyProvisionStatusService
......
# frozen_string_literal: true
module Clusters
class UpdateService < BaseService
def execute(cluster)
......
# frozen_string_literal: true
module Commits
class ChangeService < Commits::CreateService
def initialize(*args)
......
# frozen_string_literal: true
module Commits
class CherryPickService < ChangeService
def create_commit!
......
# frozen_string_literal: true
module Commits
class CreateService < ::BaseService
prepend EE::Commits::CreateService
......
# frozen_string_literal: true
module Commits
class RevertService < ChangeService
def create_commit!
......
# frozen_string_literal: true
#
# Concern that helps with getting an exclusive lease for running a block
# of code.
......
# frozen_string_literal: true
module Issues
module ResolveDiscussions
include Gitlab::Utils::StrongMemoize
......
# frozen_string_literal: true
module UpdateVisibilityLevel
def valid_visibility_level_change?(target, new_visibility)
# check that user is allowed to set specified visibility_level
......
# frozen_string_literal: true
module Users
module NewUserNotifier
def notify_new_user(user, reset_token)
......
# frozen_string_literal: true
module Users
module ParticipableService
extend ActiveSupport::Concern
......
# frozen_string_literal: true
module DeployKeys
class CreateService < Keys::BaseService
def execute
......
# frozen_string_literal: true
module DeployTokens
class CreateService < BaseService
def execute
......
# frozen_string_literal: true
module Discussions
class BaseService < ::BaseService
end
......
# frozen_string_literal: true
module Discussions
class ResolveService < Discussions::BaseService
def execute(one_or_more_discussions)
......
# frozen_string_literal: true
module Discussions
class UpdateDiffPositionService < BaseService
def execute(discussion)
......
# frozen_string_literal: true
module Emails
class BaseService
def initialize(current_user, params = {})
......
# frozen_string_literal: true
module Emails
class ConfirmService < ::Emails::BaseService
def execute(email)
......
# frozen_string_literal: true
module Emails
class CreateService < ::Emails::BaseService
prepend ::EE::Emails::CreateService
......
# frozen_string_literal: true
module Emails
class DestroyService < ::Emails::BaseService
prepend ::EE::Emails::DestroyService
......
# frozen_string_literal: true
module Events
class RenderService < BaseRenderer
def execute(events, atom_request: false)
......
# frozen_string_literal: true
module Files
class BaseService < Commits::CreateService
FileChangedError = Class.new(StandardError)
......
# frozen_string_literal: true
module Files
class CreateDirService < Files::BaseService
def create_commit!
......
# frozen_string_literal: true
module Files
class CreateService < Files::BaseService
def create_commit!
......
# frozen_string_literal: true
module Files
class DeleteService < Files::BaseService
def create_commit!
......
# frozen_string_literal: true
module Files
class MultiService < Files::BaseService
UPDATE_FILE_ACTIONS = %w(update move delete).freeze
......
# frozen_string_literal: true
module Files
class UpdateService < Files::BaseService
def create_commit!
......
# frozen_string_literal: true
module GpgKeys
class CreateService < Keys::BaseService
def execute
......
# frozen_string_literal: true
module Groups
class BaseService < ::BaseService
attr_accessor :group, :current_user, :params
......
# frozen_string_literal: true
module Groups
class CreateService < Groups::BaseService
prepend ::EE::Groups::CreateService
......
# frozen_string_literal: true
module Groups
class DestroyService < Groups::BaseService
prepend ::EE::Groups::DestroyService
......
# frozen_string_literal: true
module Groups
class NestedCreateService < Groups::BaseService
attr_reader :group_path, :visibility_level
......
# frozen_string_literal: true
module Groups
class TransferService < Groups::BaseService
ERROR_MESSAGES = {
......
# frozen_string_literal: true
module Groups
class UpdateService < Groups::BaseService
include UpdateVisibilityLevel
......
# frozen_string_literal: true
module Issuable
class BulkUpdateService < IssuableBaseService
def execute(type)
......
# frozen_string_literal: true
module Issuable
class CommonSystemNotesService < ::BaseService
prepend EE::Issuable::CommonSystemNotesService
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment