Commit 061b3561 authored by Tim Zallmann's avatar Tim Zallmann

Merge branch 'ee-remove-ide' into 'master'

Moved IDE into EE folder

See merge request gitlab-org/gitlab-ee!4784
parents 1618aa49 a77ae5ba
......@@ -324,10 +324,6 @@ module ApplicationHelper
cookies["sidebar_collapsed"] == "true"
end
def show_new_ide?(project)
cookies["new_repo"] == "true" && project.feature_available?(:ide)
end
def locale_path
asset_path("locale/#{Gitlab::I18n.locale}/app.js")
end
......
......@@ -33,20 +33,6 @@ module BlobHelper
ref)
end
def ide_edit_button(project = @project, ref = @ref, path = @path, options = {})
return unless show_new_ide?(project)
return unless blob = readable_blob(options, path, project, ref)
common_classes = "btn js-edit-ide #{options[:extra_class]}"
edit_button_tag(blob,
common_classes,
_('Web IDE'),
ide_edit_path(project, ref, path, options),
project,
ref)
end
def modify_file_button(project = @project, ref = @ref, path = @path, label:, action:, btn_class:, modal_type:)
return unless current_user
......
......@@ -14,7 +14,9 @@
= lock_file_link(html_options: { class: 'btn btn-sm path-lock' })
= edit_blob_button
-# EE-specific
= ide_edit_button
-# EE-specific
- if current_user
= replace_blob_link
= delete_blob_link
......
......@@ -78,9 +78,11 @@
= render 'projects/find_file_link'
-## EE-specific
- if show_new_ide?(@project)
= succeed " " do
= link_to ide_edit_path(@project, @id), class: 'btn btn-default' do
= _('Web IDE')
-## EE-specific
= render 'projects/buttons/download', project: @project, ref: @ref
- show_create = local_assigns.fetch(:show_create, false)
- show_new_branch_form = show_new_ide?(@project) && show_create && can?(current_user, :push_code, @project)
- dropdown_toggle_text = @ref || @project.default_branch
= form_tag switch_project_refs_path(@project), method: :get, class: "project-refs-form" do
= hidden_field_tag :destination, destination
......@@ -16,14 +15,3 @@
= dropdown_filter _("Search branches and tags")
= dropdown_content
= dropdown_loading
- if show_new_branch_form
= dropdown_footer do
%ul.dropdown-footer-list
%li
%a.dropdown-toggle-page{ href: "#" }
Create new branch
- if show_new_branch_form
.dropdown-page-two
= dropdown_title("Create new branch", options: { back: true })
= dropdown_content do
.js-new-branch-dropdown
......@@ -58,8 +58,6 @@ Rails.application.routes.draw do
get 'liveness' => 'health#liveness'
get 'readiness' => 'health#readiness'
post 'storage_check' => 'health#storage_check'
get 'ide' => 'ide#index'
get 'ide/*vueroute' => 'ide#index', format: false
resources :metrics, only: [:index]
mount Peek::Railtie => '/peek'
......@@ -78,6 +76,11 @@ Rails.application.routes.draw do
# UserCallouts
resources :user_callouts, only: [:create]
## EE-specific
get 'ide' => 'ide#index'
get 'ide/*vueroute' => 'ide#index', format: false
## EE-specific
end
# Koding route
......
......@@ -52,11 +52,11 @@ function generateEntries() {
common_vue: './vue_shared/vue_resource_interceptor.js',
locale: './locale/index.js',
main: './main.js',
ide: './ide/index.js',
raven: './raven/index.js',
webpack_runtime: './webpack.js',
// EE-only
ide: 'ee/ide/index.js',
geo_nodes: 'ee/geo_nodes',
service_desk: 'ee/projects/settings_service_desk/service_desk_bundle.js',
};
......
<script>
import { mapState } from 'vuex';
import icon from '../../../vue_shared/components/icon.vue';
import icon from '~/vue_shared/components/icon.vue';
import listItem from './list_item.vue';
import listCollapsed from './list_collapsed.vue';
......
<script>
import { mapGetters } from 'vuex';
import icon from '../../../vue_shared/components/icon.vue';
import icon from '~/vue_shared/components/icon.vue';
export default {
components: {
......
<script>
import { mapActions } from 'vuex';
import router from '~/ide/ide_router';
import icon from '../../../vue_shared/components/icon.vue';
import router from 'ee/ide/ide_router';
import icon from '~/vue_shared/components/icon.vue';
export default {
components: {
......
<script>
import icon from '~/vue_shared/components/icon.vue';
import newModal from './modal.vue';
import upload from './upload.vue';
import icon from '../../../vue_shared/components/icon.vue';
export default {
components: {
......
<script>
import { mapActions, mapState } from 'vuex';
import { __ } from '../../../locale';
import modal from '../../../vue_shared/components/modal.vue';
import { __ } from '~/locale';
import modal from '~/vue_shared/components/modal.vue';
export default {
components: {
......
import Vue from 'vue';
import VueRouter from 'vue-router';
import flash from '~/flash';
import store from './stores';
import flash from '../flash';
import {
getTreeEntry,
} from './stores/utils';
......
import Vue from 'vue';
import Translate from '~/vue_shared/translate';
import ide from './components/ide.vue';
import store from './stores';
import router from './ide_router';
import Translate from '../vue_shared/translate';
function initIde(el) {
if (!el) return null;
......@@ -18,8 +18,6 @@ function initIde(el) {
return createElement('ide', {
props: {
emptyStateSvgPath: el.dataset.emptyStateSvgPath,
noChangesStateSvgPath: el.dataset.noChangesStateSvgPath,
committedStateSvgPath: el.dataset.committedStateSvgPath,
},
});
},
......
import Vue from 'vue';
import VueResource from 'vue-resource';
import Api from '../../api';
import Api from '~/api';
Vue.use(VueResource);
......
import flash from '~/flash';
import service from '../../services';
import flash from '../../../flash';
import * as types from '../mutation_types';
export const getBranchData = (
......
import { normalizeHeaders } from '../../../lib/utils/common_utils';
import flash from '../../../flash';
import { normalizeHeaders } from '~/lib/utils/common_utils';
import flash from '~/flash';
import service from '../../services';
import * as types from '../mutation_types';
import router from '../../ide_router';
......
import flash from '~/flash';
import service from '../../services';
import flash from '../../../flash';
import * as types from '../mutation_types';
// eslint-disable-next-line import/prefer-default-export
......
import { visitUrl } from '../../../lib/utils/url_utility';
import { normalizeHeaders } from '../../../lib/utils/common_utils';
import flash from '../../../flash';
import { visitUrl } from '~/lib/utils/url_utility';
import { normalizeHeaders } from '~/lib/utils/common_utils';
import flash from '~/flash';
import service from '../../services';
import * as types from '../mutation_types';
import router from '../../ide_router';
......
import { sprintf, __ } from '~/locale';
import * as rootTypes from '~/ide/stores/mutation_types';
import { createCommitPayload, createNewMergeRequestUrl } from '~/ide/stores/utils';
import router from '~/ide/ide_router';
import service from '~/ide/services';
import * as rootTypes from 'ee/ide/stores/mutation_types';
import { createCommitPayload, createNewMergeRequestUrl } from 'ee/ide/stores/utils';
import router from 'ee/ide/ide_router';
import service from 'ee/ide/services';
import flash from '~/flash';
import { stripHtml } from '~/lib/utils/text_utility';
import * as types from './mutation_types';
......
module IdeHelper
def show_new_ide?(project)
cookies["new_repo"] == "true" && project.feature_available?(:ide)
end
def ide_edit_button(project = @project, ref = @ref, path = @path, options = {})
return unless show_new_ide?(project)
return unless blob = readable_blob(options, path, project, ref)
common_classes = "btn js-edit-ide #{options[:extra_class]}"
edit_button_tag(blob,
common_classes,
_('Web IDE'),
ide_edit_path(project, ref, path, options),
project,
ref)
end
end
import Vue from 'vue';
import store from '~/ide/stores';
import store from 'ee/ide/stores';
import commitActions from 'ee/ide/components/commit_sidebar/actions.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { resetStore } from 'spec/repo/helpers';
import { resetStore } from 'spec/ide/helpers';
describe('IDE commit sidebar actions', () => {
let vm;
......
import Vue from 'vue';
import store from '~/ide/stores';
import listCollapsed from '~/ide/components/commit_sidebar/list_collapsed.vue';
import store from 'ee/ide/stores';
import listCollapsed from 'ee/ide/components/commit_sidebar/list_collapsed.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { file } from '../../helpers';
......
import Vue from 'vue';
import listItem from '~/ide/components/commit_sidebar/list_item.vue';
import router from '~/ide/ide_router';
import listItem from 'ee/ide/components/commit_sidebar/list_item.vue';
import router from 'ee/ide/ide_router';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import { file } from '../../helpers';
......
import Vue from 'vue';
import store from '~/ide/stores';
import commitSidebarList from '~/ide/components/commit_sidebar/list.vue';
import store from 'ee/ide/stores';
import commitSidebarList from 'ee/ide/components/commit_sidebar/list.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { file } from '../../helpers';
......
import Vue from 'vue';
import store from '~/ide/stores';
import store from 'ee/ide/stores';
import radioGroup from 'ee/ide/components/commit_sidebar/radio_group.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { resetStore } from 'spec/repo/helpers';
import { resetStore } from 'spec/ide/helpers';
describe('IDE commit sidebar radio group', () => {
let vm;
......
import Vue from 'vue';
import store from '~/ide/stores';
import ideContextBar from '~/ide/components/ide_context_bar.vue';
import store from 'ee/ide/stores';
import ideContextBar from 'ee/ide/components/ide_context_bar.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
describe('Multi-file editor right context bar', () => {
......
import Vue from 'vue';
import store from '~/ide/stores';
import ideRepoTree from '~/ide/components/ide_repo_tree.vue';
import store from 'ee/ide/stores';
import ideRepoTree from 'ee/ide/components/ide_repo_tree.vue';
import { file, resetStore } from '../helpers';
describe('IdeRepoTree', () => {
......
import Vue from 'vue';
import store from '~/ide/stores';
import ideSidebar from '~/ide/components/ide_side_bar.vue';
import store from 'ee/ide/stores';
import ideSidebar from 'ee/ide/components/ide_side_bar.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { resetStore } from '../helpers';
......
import Vue from 'vue';
import store from '~/ide/stores';
import ide from '~/ide/components/ide.vue';
import store from 'ee/ide/stores';
import ide from 'ee/ide/components/ide.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { file, resetStore } from '../helpers';
......
import Vue from 'vue';
import store from '~/ide/stores';
import newBranchForm from '~/ide/components/new_branch_form.vue';
import store from 'ee/ide/stores';
import newBranchForm from 'ee/ide/components/new_branch_form.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { resetStore } from '../helpers';
......
import Vue from 'vue';
import store from '~/ide/stores';
import newDropdown from '~/ide/components/new_dropdown/index.vue';
import store from 'ee/ide/stores';
import newDropdown from 'ee/ide/components/new_dropdown/index.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { resetStore } from '../../helpers';
......
import Vue from 'vue';
import store from '~/ide/stores';
import service from '~/ide/services';
import modal from '~/ide/components/new_dropdown/modal.vue';
import store from 'ee/ide/stores';
import service from 'ee/ide/services';
import modal from 'ee/ide/components/new_dropdown/modal.vue';
import router from 'ee/ide/ide_router';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { file, resetStore } from '../../helpers';
......@@ -38,6 +39,8 @@ describe('new file modal component', () => {
submodules: [{ name: 'submodule' }],
}),
}));
spyOn(router, 'push');
});
afterEach(() => {
......
import Vue from 'vue';
import upload from '~/ide/components/new_dropdown/upload.vue';
import store from '~/ide/stores';
import service from '~/ide/services';
import upload from 'ee/ide/components/new_dropdown/upload.vue';
import store from 'ee/ide/stores';
import service from 'ee/ide/services';
import router from 'ee/ide/ide_router';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { resetStore } from '../../helpers';
......@@ -38,6 +39,8 @@ describe('new dropdown upload', () => {
}),
}));
spyOn(router, 'push');
const Component = Vue.extend(upload);
store.state.projects.abcproject = {
......
import Vue from 'vue';
import store from '~/ide/stores';
import service from '~/ide/services';
import repoCommitSection from '~/ide/components/repo_commit_section.vue';
import store from 'ee/ide/stores';
import service from 'ee/ide/services';
import repoCommitSection from 'ee/ide/components/repo_commit_section.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import getSetTimeoutPromise from 'spec/helpers/set_timeout_promise_helper';
import { file, resetStore } from '../helpers';
......
import Vue from 'vue';
import store from '~/ide/stores';
import repoEditButton from '~/ide/components/repo_edit_button.vue';
import store from 'ee/ide/stores';
import repoEditButton from 'ee/ide/components/repo_edit_button.vue';
import { file, resetStore } from '../helpers';
describe('RepoEditButton', () => {
......
import Vue from 'vue';
import store from '~/ide/stores';
import repoEditor from '~/ide/components/repo_editor.vue';
import monacoLoader from '~/ide/monaco_loader';
import Editor from '~/ide/lib/editor';
import store from 'ee/ide/stores';
import repoEditor from 'ee/ide/components/repo_editor.vue';
import monacoLoader from 'ee/ide/monaco_loader';
import Editor from 'ee/ide/lib/editor';
import { file, resetStore } from '../helpers';
describe('RepoEditor', () => {
......
import Vue from 'vue';
import store from '~/ide/stores';
import repoFileButtons from '~/ide/components/repo_file_buttons.vue';
import store from 'ee/ide/stores';
import repoFileButtons from 'ee/ide/components/repo_file_buttons.vue';
import { file, resetStore } from '../helpers';
describe('RepoFileButtons', () => {
......
import Vue from 'vue';
import store from '~/ide/stores';
import repoFile from '~/ide/components/repo_file.vue';
import store from 'ee/ide/stores';
import repoFile from 'ee/ide/components/repo_file.vue';
import { file, resetStore } from '../helpers';
describe('RepoFile', () => {
......
import Vue from 'vue';
import store from '~/ide/stores';
import repoLoadingFile from '~/ide/components/repo_loading_file.vue';
import store from 'ee/ide/stores';
import repoLoadingFile from 'ee/ide/components/repo_loading_file.vue';
import { resetStore } from '../helpers';
describe('RepoLoadingFile', () => {
......
import Vue from 'vue';
import store from '~/ide/stores';
import repoPrevDirectory from '~/ide/components/repo_prev_directory.vue';
import store from 'ee/ide/stores';
import repoPrevDirectory from 'ee/ide/components/repo_prev_directory.vue';
import { resetStore } from '../helpers';
describe('RepoPrevDirectory', () => {
......
import Vue from 'vue';
import store from '~/ide/stores';
import repoPreview from '~/ide/components/repo_preview.vue';
import store from 'ee/ide/stores';
import repoPreview from 'ee/ide/components/repo_preview.vue';
import { file, resetStore } from '../helpers';
describe('RepoPreview', () => {
......
import Vue from 'vue';
import store from '~/ide/stores';
import repoTab from '~/ide/components/repo_tab.vue';
import store from 'ee/ide/stores';
import repoTab from 'ee/ide/components/repo_tab.vue';
import router from 'ee/ide/ide_router';
import { file, resetStore } from '../helpers';
describe('RepoTab', () => {
......@@ -15,6 +16,10 @@ describe('RepoTab', () => {
}).$mount();
}
beforeEach(() => {
spyOn(router, 'push');
});
afterEach(() => {
resetStore(vm.$store);
});
......
import Vue from 'vue';
import store from '~/ide/stores';
import repoTabs from '~/ide/components/repo_tabs.vue';
import store from 'ee/ide/stores';
import repoTabs from 'ee/ide/components/repo_tabs.vue';
import { file, resetStore } from '../helpers';
describe('RepoTabs', () => {
......
import { decorateData } from '~/ide/stores/utils';
import state from '~/ide/stores/state';
import { decorateData } from 'ee/ide/stores/utils';
import state from 'ee/ide/stores/state';
import commitState from 'ee/ide/stores/modules/commit/state';
export const resetStore = (store) => {
......
import Disposable from '~/ide/lib/common/disposable';
import Disposable from 'ee/ide/lib/common/disposable';
describe('Multi-file editor library disposable class', () => {
let instance;
......
/* global monaco */
import monacoLoader from '~/ide/monaco_loader';
import ModelManager from '~/ide/lib/common/model_manager';
import monacoLoader from 'ee/ide/monaco_loader';
import ModelManager from 'ee/ide/lib/common/model_manager';
import { file } from '../../helpers';
describe('Multi-file editor library model manager', () => {
......
/* global monaco */
import monacoLoader from '~/ide/monaco_loader';
import Model from '~/ide/lib/common/model';
import monacoLoader from 'ee/ide/monaco_loader';
import Model from 'ee/ide/lib/common/model';
import { file } from '../../helpers';
describe('Multi-file editor library model', () => {
......
/* global monaco */
import monacoLoader from '~/ide/monaco_loader';
import editor from '~/ide/lib/editor';
import DecorationsController from '~/ide/lib/decorations/controller';
import Model from '~/ide/lib/common/model';
import monacoLoader from 'ee/ide/monaco_loader';
import editor from 'ee/ide/lib/editor';
import DecorationsController from 'ee/ide/lib/decorations/controller';
import Model from 'ee/ide/lib/common/model';
import { file } from '../../helpers';
describe('Multi-file editor library decorations controller', () => {
......
/* global monaco */
import monacoLoader from '~/ide/monaco_loader';
import editor from '~/ide/lib/editor';
import ModelManager from '~/ide/lib/common/model_manager';
import DecorationsController from '~/ide/lib/decorations/controller';
import DirtyDiffController, { getDiffChangeType, getDecorator } from '~/ide/lib/diff/controller';
import { computeDiff } from '~/ide/lib/diff/diff';
import monacoLoader from 'ee/ide/monaco_loader';
import editor from 'ee/ide/lib/editor';
import ModelManager from 'ee/ide/lib/common/model_manager';
import DecorationsController from 'ee/ide/lib/decorations/controller';
import DirtyDiffController, { getDiffChangeType, getDecorator } from 'ee/ide/lib/diff/controller';
import { computeDiff } from 'ee/ide/lib/diff/diff';
import { file } from '../../helpers';
describe('Multi-file editor library dirty diff controller', () => {
......
import { computeDiff } from '~/ide/lib/diff/diff';
import { computeDiff } from 'ee/ide/lib/diff/diff';
describe('Multi-file editor library diff calculator', () => {
describe('computeDiff', () => {
......
import editorOptions from '~/ide/lib/editor_options';
import editorOptions from 'ee/ide/lib/editor_options';
describe('Multi-file editor library editor options', () => {
it('returns an array', () => {
......
/* global monaco */
import monacoLoader from '~/ide/monaco_loader';
import editor from '~/ide/lib/editor';
import monacoLoader from 'ee/ide/monaco_loader';
import editor from 'ee/ide/lib/editor';
import { file } from '../helpers';
describe('Multi-file editor library', () => {
......
import monacoContext from 'monaco-editor/dev/vs/loader';
import monacoLoader from '~/ide/monaco_loader';
import monacoLoader from 'ee/ide/monaco_loader';
describe('MonacoLoader', () => {
it('calls require.config and exports require', () => {
......
import store from '~/ide/stores';
import service from '~/ide/services';
import store from 'ee/ide/stores';
import service from 'ee/ide/services';
import { resetStore } from '../../helpers';
describe('Multi-file store branch actions', () => {
......
import Vue from 'vue';
import store from '~/ide/stores';
import service from '~/ide/services';
import store from 'ee/ide/stores';
import service from 'ee/ide/services';
import router from 'ee/ide/ide_router';
import { file, resetStore } from '../../helpers';
describe('Multi-file store file actions', () => {
beforeEach(() => {
spyOn(router, 'push');
});
afterEach(() => {
resetStore(store);
});
......
import Vue from 'vue';
import store from '~/ide/stores';
import service from '~/ide/services';
import store from 'ee/ide/stores';
import service from 'ee/ide/services';
import router from 'ee/ide/ide_router';
import { file, resetStore } from '../../helpers';
describe('Multi-file store tree actions', () => {
......@@ -13,6 +14,8 @@ describe('Multi-file store tree actions', () => {
};
beforeEach(() => {
spyOn(router, 'push');
store.state.currentProjectId = 'abcproject';
store.state.currentBranchId = 'master';
store.state.projects.abcproject = {
......
import Vue from 'vue';
import * as urlUtils from '~/lib/utils/url_utility';
import store from '~/ide/stores';
import store from 'ee/ide/stores';
import router from 'ee/ide/ide_router';
import { resetStore, file } from '../helpers';
describe('Multi-file store actions', () => {
beforeEach(() => {
spyOn(router, 'push');
});
afterEach(() => {
resetStore(store);
});
......
import * as getters from '~/ide/stores/getters';
import state from '~/ide/stores/state';
import * as getters from 'ee/ide/stores/getters';
import state from 'ee/ide/stores/state';
import { file } from '../helpers';
describe('Multi-file store getters', () => {
......
import store from '~/ide/stores';
import service from '~/ide/services';
import router from '~/ide/ide_router';
import store from 'ee/ide/stores';
import service from 'ee/ide/services';
import router from 'ee/ide/ide_router';
import * as urlUtils from '~/lib/utils/url_utility';
import eventHub from 'ee/ide/eventhub';
import * as consts from 'ee/ide/stores/modules/commit/constants';
import { resetStore, file } from 'spec/repo/helpers';
import { resetStore, file } from 'spec/ide/helpers';
describe('IDE commit module actions', () => {
beforeEach(() => {
spyOn(router, 'push');
});
afterEach(() => {
resetStore(store);
});
......@@ -170,7 +174,6 @@ describe('IDE commit module actions', () => {
beforeEach(() => {
spyOn(eventHub, '$emit');
spyOn(router, 'push');
f = file('changedFile');
Object.assign(f, {
......@@ -287,7 +290,7 @@ describe('IDE commit module actions', () => {
describe('commitChanges', () => {
beforeEach(() => {
spyOn(router, 'push');
spyOn(urlUtils, 'visitUrl');
document.body.innerHTML += '<div class="flash-container"></div>';
......@@ -380,8 +383,6 @@ describe('IDE commit module actions', () => {
});
it('redirects to new merge request page', (done) => {
spyOn(urlUtils, 'visitUrl');
store.state.commit.commitAction = '3';
store.dispatch('commit/commitChanges')
......
import mutations from '~/ide/stores/mutations/branch';
import state from '~/ide/stores/state';
import mutations from 'ee/ide/stores/mutations/branch';
import state from 'ee/ide/stores/state';
describe('Multi-file store branch mutations', () => {
let localState;
......
import mutations from '~/ide/stores/mutations/file';
import state from '~/ide/stores/state';
import mutations from 'ee/ide/stores/mutations/file';
import state from 'ee/ide/stores/state';
import { file } from '../../helpers';
describe('Multi-file store file mutations', () => {
......
import mutations from '~/ide/stores/mutations/tree';
import state from '~/ide/stores/state';
import mutations from 'ee/ide/stores/mutations/tree';
import state from 'ee/ide/stores/state';
import { file } from '../../helpers';
describe('Multi-file store tree mutations', () => {
......
import mutations from '~/ide/stores/mutations';
import state from '~/ide/stores/state';
import mutations from 'ee/ide/stores/mutations';
import state from 'ee/ide/stores/state';
import { file } from '../helpers';
describe('Multi-file store mutations', () => {
......
import * as utils from '~/ide/stores/utils';
import state from '~/ide/stores/state';
import * as utils from 'ee/ide/stores/utils';
import state from 'ee/ide/stores/state';
import { file } from '../helpers';
describe('Multi-file store utils', () => {
......
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