Commit e440c869 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 7d81614e
...@@ -273,7 +273,7 @@ static-analysis: ...@@ -273,7 +273,7 @@ static-analysis:
script: script:
- scripts/static-analysis - scripts/static-analysis
cache: cache:
key: "debian-stretch-ruby-2.6.3-and-rubocop" key: "debian-stretch-ruby-2.6-and-rubocop"
paths: paths:
- vendor/ruby - vendor/ruby
- tmp/rubocop_cache - tmp/rubocop_cache
......
...@@ -79,7 +79,7 @@ Instructions on how to start GitLab and how to run the tests can be found in the ...@@ -79,7 +79,7 @@ Instructions on how to start GitLab and how to run the tests can be found in the
GitLab is a Ruby on Rails application that runs on the following software: GitLab is a Ruby on Rails application that runs on the following software:
- Ubuntu/Debian/CentOS/RHEL/OpenSUSE - Ubuntu/Debian/CentOS/RHEL/OpenSUSE
- Ruby (MRI) 2.6.3 - Ruby (MRI) 2.6.5
- Git 2.8.4+ - Git 2.8.4+
- Redis 2.8+ - Redis 2.8+
- PostgreSQL (preferred) or MySQL - PostgreSQL (preferred) or MySQL
......
<script> <script>
/* eslint-disable @gitlab/vue-i18n/no-bare-strings */
import _ from 'underscore'; import _ from 'underscore';
import { GlTooltipDirective, GlLink, GlBadge } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import { __, n__, sprintf } from '~/locale';
import { slugify } from '~/lib/utils/text_utility'; import { slugify } from '~/lib/utils/text_utility';
import { getLocationHash } from '~/lib/utils/url_utility'; import { getLocationHash } from '~/lib/utils/url_utility';
import { scrollToElement } from '~/lib/utils/common_utils'; import { scrollToElement } from '~/lib/utils/common_utils';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import ReleaseBlockFooter from './release_block_footer.vue';
import EvidenceBlock from './evidence_block.vue'; import EvidenceBlock from './evidence_block.vue';
import ReleaseBlockAssets from './release_block_assets.vue';
import ReleaseBlockFooter from './release_block_footer.vue';
import ReleaseBlockHeader from './release_block_header.vue';
import ReleaseBlockMetadata from './release_block_metadata.vue';
import ReleaseBlockMilestoneInfo from './release_block_milestone_info.vue'; import ReleaseBlockMilestoneInfo from './release_block_milestone_info.vue';
export default { export default {
name: 'ReleaseBlock', name: 'ReleaseBlock',
components: { components: {
EvidenceBlock, EvidenceBlock,
GlLink, ReleaseBlockAssets,
GlBadge,
Icon,
UserAvatarLink,
ReleaseBlockFooter, ReleaseBlockFooter,
ReleaseBlockHeader,
ReleaseBlockMetadata,
ReleaseBlockMilestoneInfo, ReleaseBlockMilestoneInfo,
}, },
directives: { mixins: [glFeatureFlagsMixin()],
GlTooltip: GlTooltipDirective,
},
mixins: [timeagoMixin, glFeatureFlagsMixin()],
props: { props: {
release: { release: {
type: Object, type: Object,
...@@ -45,45 +38,14 @@ export default { ...@@ -45,45 +38,14 @@ export default {
id() { id() {
return slugify(this.release.tag_name); return slugify(this.release.tag_name);
}, },
releasedTimeAgo() {
return sprintf(__('released %{time}'), {
time: this.timeFormatted(this.release.released_at),
});
},
userImageAltDescription() {
return this.author && this.author.username
? sprintf(__("%{username}'s avatar"), { username: this.author.username })
: null;
},
commit() {
return this.release.commit || {};
},
commitUrl() {
return this.release.commit_path;
},
tagUrl() {
return this.release.tag_path;
},
assets() { assets() {
return this.release.assets || {}; return this.release.assets || {};
}, },
author() {
return this.release.author || {};
},
hasAuthor() {
return !_.isEmpty(this.author);
},
hasEvidence() { hasEvidence() {
return Boolean(this.release.evidence_sha); return Boolean(this.release.evidence_sha);
}, },
shouldRenderMilestones() { milestones() {
return !_.isEmpty(this.release.milestones); return this.release.milestones || [];
},
labelText() {
return n__('Milestone', 'Milestones', this.release.milestones.length);
},
shouldShowEditButton() {
return Boolean(this.release._links && this.release._links.edit_url);
}, },
shouldShowEvidence() { shouldShowEvidence() {
return this.glFeatures.releaseEvidenceCollection; return this.glFeatures.releaseEvidenceCollection;
...@@ -91,6 +53,11 @@ export default { ...@@ -91,6 +53,11 @@ export default {
shouldShowFooter() { shouldShowFooter() {
return this.glFeatures.releaseIssueSummary; return this.glFeatures.releaseIssueSummary;
}, },
shouldRenderAssets() {
return Boolean(
this.assets.links.length || (this.assets.sources && this.assets.sources.length),
);
},
shouldRenderReleaseMetaData() { shouldRenderReleaseMetaData() {
return !this.glFeatures.releaseIssueSummary; return !this.glFeatures.releaseIssueSummary;
}, },
...@@ -113,127 +80,15 @@ export default { ...@@ -113,127 +80,15 @@ export default {
</script> </script>
<template> <template>
<div :id="id" :class="{ 'bg-line-target-blue': isHighlighted }" class="card release-block"> <div :id="id" :class="{ 'bg-line-target-blue': isHighlighted }" class="card release-block">
<div class="card-header d-flex align-items-center bg-white pr-0"> <release-block-header :release="release" />
<h2 class="card-title my-2 mr-auto gl-font-size-20">
{{ release.name }}
<gl-badge v-if="release.upcoming_release" variant="warning" class="align-middle">{{
__('Upcoming Release')
}}</gl-badge>
</h2>
<gl-link
v-if="shouldShowEditButton"
v-gl-tooltip
class="btn btn-default append-right-10 js-edit-button ml-2"
:title="__('Edit this release')"
:href="release._links.edit_url"
>
<icon name="pencil" />
</gl-link>
</div>
<div class="card-body"> <div class="card-body">
<div v-if="shouldRenderMilestoneInfo"> <div v-if="shouldRenderMilestoneInfo">
<release-block-milestone-info :milestones="release.milestones" /> <release-block-milestone-info :milestones="milestones" />
<hr class="mb-3 mt-0" /> <hr class="mb-3 mt-0" />
</div> </div>
<div v-if="shouldRenderReleaseMetaData" class="card-subtitle d-flex flex-wrap text-secondary"> <release-block-metadata v-if="shouldRenderReleaseMetaData" :release="release" />
<div class="append-right-8"> <release-block-assets v-if="shouldRenderAssets" :assets="assets" />
<icon name="commit" class="align-middle" />
<gl-link v-if="commitUrl" v-gl-tooltip.bottom :title="commit.title" :href="commitUrl">
{{ commit.short_id }}
</gl-link>
<span v-else v-gl-tooltip.bottom :title="commit.title">{{ commit.short_id }}</span>
</div>
<div class="append-right-8">
<icon name="tag" class="align-middle" />
<gl-link v-if="tagUrl" v-gl-tooltip.bottom :title="__('Tag')" :href="tagUrl">
{{ release.tag_name }}
</gl-link>
<span v-else v-gl-tooltip.bottom :title="__('Tag')">{{ release.tag_name }}</span>
</div>
<template v-if="shouldRenderMilestones">
<div class="js-milestone-list-label">
<icon name="flag" class="align-middle" />
<span class="js-label-text">{{ labelText }}</span>
</div>
<template v-for="(milestone, index) in release.milestones">
<gl-link
:key="milestone.id"
v-gl-tooltip
:title="milestone.description"
:href="milestone.web_url"
class="append-right-4 prepend-left-4 js-milestone-link"
>
{{ milestone.title }}
</gl-link>
<template v-if="index !== release.milestones.length - 1">
&bull;
</template>
</template>
</template>
<div class="append-right-4">
&bull;
<span v-gl-tooltip.bottom :title="tooltipTitle(release.released_at)">
{{ releasedTimeAgo }}
</span>
</div>
<div v-if="hasAuthor" class="d-flex">
by
<user-avatar-link
class="prepend-left-4"
:link-href="author.web_url"
:img-src="author.avatar_url"
:img-alt="userImageAltDescription"
:tooltip-text="author.username"
/>
</div>
</div>
<div
v-if="assets.links.length || (assets.sources && assets.sources.length)"
class="card-text prepend-top-default"
>
<b>
{{ __('Assets') }}
<span class="js-assets-count badge badge-pill">{{ assets.count }}</span>
</b>
<ul v-if="assets.links.length" class="pl-0 mb-0 prepend-top-8 list-unstyled js-assets-list">
<li v-for="link in assets.links" :key="link.name" class="append-bottom-8">
<gl-link v-gl-tooltip.bottom :title="__('Download asset')" :href="link.url">
<icon name="package" class="align-middle append-right-4 align-text-bottom" />
{{ link.name }}
<span v-if="link.external">{{ __('(external source)') }}</span>
</gl-link>
</li>
</ul>
<div v-if="assets.sources && assets.sources.length" class="dropdown">
<button
type="button"
class="btn btn-link"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<icon name="doc-code" class="align-top append-right-4" />
{{ __('Source code') }}
<icon name="arrow-down" />
</button>
<div class="js-sources-dropdown dropdown-menu">
<li v-for="asset in assets.sources" :key="asset.url">
<gl-link :href="asset.url">{{ __('Download') }} {{ asset.format }}</gl-link>
</li>
</div>
</div>
</div>
<evidence-block v-if="hasEvidence && shouldShowEvidence" :release="release" /> <evidence-block v-if="hasEvidence && shouldShowEvidence" :release="release" />
<div class="card-text prepend-top-default"> <div class="card-text prepend-top-default">
......
<script>
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
export default {
name: 'ReleaseBlockAssets',
components: {
GlLink,
Icon,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
assets: {
type: Object,
required: true,
},
},
computed: {
hasAssets() {
return Boolean(this.assets.count);
},
},
};
</script>
<template>
<div class="card-text prepend-top-default">
<b>
{{ __('Assets') }}
<span class="js-assets-count badge badge-pill">{{ assets.count }}</span>
</b>
<ul v-if="assets.links.length" class="pl-0 mb-0 prepend-top-8 list-unstyled js-assets-list">
<li v-for="link in assets.links" :key="link.name" class="append-bottom-8">
<gl-link v-gl-tooltip.bottom :title="__('Download asset')" :href="link.url">
<icon name="package" class="align-middle append-right-4 align-text-bottom" />
{{ link.name }}
<span v-if="link.external">{{ __('(external source)') }}</span>
</gl-link>
</li>
</ul>
<div v-if="hasAssets" class="dropdown">
<button
type="button"
class="btn btn-link"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<icon name="doc-code" class="align-top append-right-4" />
{{ __('Source code') }}
<icon name="arrow-down" />
</button>
<div class="js-sources-dropdown dropdown-menu">
<li v-for="asset in assets.sources" :key="asset.url">
<gl-link :href="asset.url">{{ __('Download') }} {{ asset.format }}</gl-link>
</li>
</div>
</div>
</div>
</template>
<script>
import { __, sprintf } from '~/locale';
import { GlSprintf } from '@gitlab/ui';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
export default {
name: 'ReleaseBlockAuthor',
components: {
GlSprintf,
UserAvatarLink,
},
props: {
author: {
type: Object,
required: true,
},
},
computed: {
userImageAltDescription() {
return this.author && this.author.username
? sprintf(__("%{username}'s avatar"), { username: this.author.username })
: null;
},
},
};
</script>
<template>
<div class="d-flex">
<gl-sprintf message="by %{user}">
<template #user>
<user-avatar-link
class="prepend-left-4"
:link-href="author.web_url"
:img-src="author.avatar_url"
:img-alt="userImageAltDescription"
:tooltip-text="author.username"
/>
</template>
</gl-sprintf>
</div>
</template>
<script>
import { GlTooltipDirective, GlLink, GlBadge } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
export default {
name: 'ReleaseBlockHeader',
components: {
GlLink,
GlBadge,
Icon,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
release: {
type: Object,
required: true,
},
},
computed: {
shouldShowEditButton() {
return Boolean(this.release._links && this.release._links.edit_url);
},
},
};
</script>
<template>
<div class="card-header d-flex align-items-center bg-white pr-0">
<h2 class="card-title my-2 mr-auto gl-font-size-20">
{{ release.name }}
<gl-badge v-if="release.upcoming_release" variant="warning" class="align-middle">{{
__('Upcoming Release')
}}</gl-badge>
</h2>
<gl-link
v-if="shouldShowEditButton"
v-gl-tooltip
class="btn btn-default append-right-10 js-edit-button ml-2"
:title="__('Edit this release')"
:href="release._links.edit_url"
>
<icon name="pencil" />
</gl-link>
</div>
</template>
<script>
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import ReleaseBlockAuthor from './release_block_author.vue';
import ReleaseBlockMilestones from './release_block_milestones.vue';
export default {
name: 'ReleaseBlockMetadata',
components: {
Icon,
GlLink,
ReleaseBlockAuthor,
ReleaseBlockMilestones,
},
directives: {
GlTooltip: GlTooltipDirective,
},
mixins: [timeagoMixin],
props: {
release: {
type: Object,
required: true,
},
},
computed: {
author() {
return this.release.author;
},
commit() {
return this.release.commit || {};
},
commitUrl() {
return this.release.commit_path;
},
hasAuthor() {
return Boolean(this.author);
},
releasedTimeAgo() {
return sprintf(__('released %{time}'), {
time: this.timeFormatted(this.release.released_at),
});
},
shouldRenderMilestones() {
return Boolean(this.release.milestones?.length);
},
tagUrl() {
return this.release.tag_path;
},
},
};
</script>
<template>
<div class="card-subtitle d-flex flex-wrap text-secondary">
<div class="append-right-8">
<icon name="commit" class="align-middle" />
<gl-link v-if="commitUrl" v-gl-tooltip.bottom :title="commit.title" :href="commitUrl">
{{ commit.short_id }}
</gl-link>
<span v-else v-gl-tooltip.bottom :title="commit.title">{{ commit.short_id }}</span>
</div>
<div class="append-right-8">
<icon name="tag" class="align-middle" />
<gl-link v-if="tagUrl" v-gl-tooltip.bottom :title="__('Tag')" :href="tagUrl">
{{ release.tag_name }}
</gl-link>
<span v-else v-gl-tooltip.bottom :title="__('Tag')">{{ release.tag_name }}</span>
</div>
<release-block-milestones v-if="shouldRenderMilestones" :milestones="release.milestones" />
<div class="append-right-4">
&bull;
<span v-gl-tooltip.bottom :title="tooltipTitle(release.released_at)">
{{ releasedTimeAgo }}
</span>
</div>
<release-block-author v-if="hasAuthor" :author="author" />
</div>
</template>
<script>
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
import { n__ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
export default {
name: 'ReleaseBlockMilestones',
components: {
GlLink,
Icon,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
milestones: {
type: Array,
required: true,
},
},
computed: {
labelText() {
return n__('Milestone', 'Milestones', this.milestones.length);
},
},
};
</script>
<template>
<div>
<div class="js-milestone-list-label">
<icon name="flag" class="align-middle" />
<span class="js-label-text">{{ labelText }}</span>
</div>
<template v-for="(milestone, index) in milestones">
<gl-link
:key="milestone.id"
v-gl-tooltip
:title="milestone.description"
:href="milestone.web_url"
class="mx-1 js-milestone-link"
>
{{ milestone.title }}
</gl-link>
<template v-if="index !== milestones.length - 1">
&bull;
</template>
</template>
</div>
</template>
---
title: Update Ruby to 2.6.5
merge_request: 22417
author:
type: other
...@@ -447,7 +447,7 @@ Each line contains a JSON line that can be ingested by Elasticsearch. For exampl ...@@ -447,7 +447,7 @@ Each line contains a JSON line that can be ingested by Elasticsearch. For exampl
}, },
"runtime": { "runtime": {
"name": "ruby", "name": "ruby",
"version": "ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]" "version": "ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]"
} }
}, },
"extra.project_id": 55, "extra.project_id": 55,
......
...@@ -157,7 +157,7 @@ Some basic Ruby runtime metrics are available: ...@@ -157,7 +157,7 @@ Some basic Ruby runtime metrics are available:
| `ruby_process_resident_memory_bytes` | Gauge | 12.0 | Memory usage by process, measured in bytes | | `ruby_process_resident_memory_bytes` | Gauge | 12.0 | Memory usage by process, measured in bytes |
| `ruby_process_start_time_seconds` | Gauge | 12.0 | UNIX timestamp of process start time | | `ruby_process_start_time_seconds` | Gauge | 12.0 | UNIX timestamp of process start time |
[GC.stat]: https://ruby-doc.org/core-2.6.3/GC.html#method-c-stat [GC.stat]: https://ruby-doc.org/core-2.6.5/GC.html#method-c-stat
## Unicorn Metrics ## Unicorn Metrics
......
...@@ -42,9 +42,9 @@ The current stages are: ...@@ -42,9 +42,9 @@ The current stages are:
## Default image ## Default image
The default image is currently The default image is currently
`registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.3-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33`. `registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.6.5-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33`.
It includes Ruby 2.6.3, Go 1.12, Git 2.24, Git LFS 2.9, Chrome 73, Node 12, Yarn 1.16, It includes Ruby 2.6.5, Go 1.12, Git 2.24, Git LFS 2.9, Chrome 73, Node 12, Yarn 1.16,
PostgreSQL 9.6, and Graphics Magick 1.3.33. PostgreSQL 9.6, and Graphics Magick 1.3.33.
The images used in our pipelines are configured in the The images used in our pipelines are configured in the
......
...@@ -224,9 +224,9 @@ Download Ruby and compile it: ...@@ -224,9 +224,9 @@ Download Ruby and compile it:
```sh ```sh
mkdir /tmp/ruby && cd /tmp/ruby mkdir /tmp/ruby && cd /tmp/ruby
curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.gz curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.5.tar.gz
echo '2347ed6ca5490a104ebd5684d2b9b5eefa6cd33c ruby-2.6.3.tar.gz' | shasum -c - && tar xzf ruby-2.6.3.tar.gz echo '1416ce288fb8bfeae07a12b608540318c9cace71 ruby-2.6.5.tar.gz' | shasum -c - && tar xzf ruby-2.6.5.tar.gz
cd ruby-2.6.3 cd ruby-2.6.5
./configure --disable-install-rdoc ./configure --disable-install-rdoc
make make
......
...@@ -56,9 +56,9 @@ Download Ruby and compile it: ...@@ -56,9 +56,9 @@ Download Ruby and compile it:
```bash ```bash
mkdir /tmp/ruby && cd /tmp/ruby mkdir /tmp/ruby && cd /tmp/ruby
curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.gz curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.5.tar.gz
echo '2347ed6ca5490a104ebd5684d2b9b5eefa6cd33c ruby-2.6.3.tar.gz' | shasum -c - && tar xzf ruby-2.6.3.tar.gz echo '1416ce288fb8bfeae07a12b608540318c9cace71 ruby-2.6.5.tar.gz' | shasum -c - && tar xzf ruby-2.6.5.tar.gz
cd ruby-2.6.3 cd ruby-2.6.5
./configure --disable-install-rdoc ./configure --disable-install-rdoc
make make
......
...@@ -228,8 +228,8 @@ module Gitlab ...@@ -228,8 +228,8 @@ module Gitlab
{} # augmented in EE {} # augmented in EE
end end
def count(relation, count_by: nil, fallback: -1) def count(relation, fallback: -1)
count_by ? relation.count(count_by) : relation.count relation.count
rescue ActiveRecord::StatementInvalid rescue ActiveRecord::StatementInvalid
fallback fallback
end end
......
FROM ruby:2.6.3-alpine FROM ruby:2.6.5-alpine
ADD ./ /app/ ADD ./ /app/
WORKDIR /app WORKDIR /app
ENV RACK_ENV production ENV RACK_ENV production
......
...@@ -261,7 +261,7 @@ ...@@ -261,7 +261,7 @@
"context": { "context": {
"server": { "server": {
"runtime": { "runtime": {
"version": "ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]", "version": "ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]",
"name": "ruby" "name": "ruby"
}, },
"os": { "os": {
...@@ -297,4 +297,4 @@ ...@@ -297,4 +297,4 @@
] ]
}, },
"groupID": "1378364652" "groupID": "1378364652"
} }
\ No newline at end of file
...@@ -34,7 +34,7 @@ export const utilsMockData = [ ...@@ -34,7 +34,7 @@ export const utilsMockData = [
content: [ content: [
{ {
text: text:
'Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.3-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33', 'Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.6.5-golang-1.12-git-2.24-lfs-2.9-chrome-73.0-node-12.x-yarn-1.16-postgresql-9.6-graphicsmagick-1.3.33',
}, },
], ],
section: 'prepare-executor', section: 'prepare-executor',
......
...@@ -339,12 +339,6 @@ describe Gitlab::UsageData do ...@@ -339,12 +339,6 @@ describe Gitlab::UsageData do
expect(described_class.count(relation)).to eq(1) expect(described_class.count(relation)).to eq(1)
end end
it 'returns the count for count_by when provided' do
allow(relation).to receive(:count).with(:creator_id).and_return(2)
expect(described_class.count(relation, count_by: :creator_id)).to eq(2)
end
it 'returns the fallback value when counting fails' do it 'returns the fallback value when counting fails' do
allow(relation).to receive(:count).and_raise(ActiveRecord::StatementInvalid.new('')) allow(relation).to receive(:count).and_raise(ActiveRecord::StatementInvalid.new(''))
......
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