Commit 81fe53f6 authored by Dietmar Maurer's avatar Dietmar Maurer

add more gettext markers

parent 4711b80c
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -31,7 +31,7 @@ Ext.define('PVE.dc.UserEdit', {
verifypw = Ext.createWidget('textfield', {
inputType: 'password',
fieldLabel: gettext('Verify Password'),
fieldLabel: gettext('Confirm password'),
name: 'verifypassword',
submitValue: false,
disabled: true,
......
......@@ -20,7 +20,7 @@ Ext.define('PVE.window.PasswordEdit', {
verifypw = Ext.createWidget('textfield', {
inputType: 'password',
fieldLabel: gettext('Verify Password'),
fieldLabel: gettext('Confirm password'),
name: 'verifypassword',
submitValue: false,
validator: validate_pw
......
......@@ -19,7 +19,7 @@ Ext.define('PVE.openvz.CreateWizard', {
var storagesel = Ext.create('PVE.form.StorageSelector', {
name: 'storage',
fieldLabel: 'Storage',
fieldLabel: gettext('Storage'),
storageContent: 'rootdir',
autoSelect: true,
allowBlank: false
......@@ -28,13 +28,13 @@ Ext.define('PVE.openvz.CreateWizard', {
var tmplsel = Ext.create('PVE.form.FileSelector', {
name: 'ostemplate',
storageContent: 'vztmpl',
fieldLabel: 'OS template',
fieldLabel: gettext('Template'),
allowBlank: false
});
var tmplstoragesel = Ext.create('PVE.form.StorageSelector', {
name: 'tmplstorage',
fieldLabel: 'Storage',
fieldLabel: gettext('Storage'),
storageContent: 'vztmpl',
autoSelect: true,
allowBlank: false,
......@@ -59,12 +59,12 @@ Ext.define('PVE.openvz.CreateWizard', {
items: [
{
xtype: 'inputpanel',
title: 'General',
title: gettext('General'),
column1: [
{
xtype: 'PVE.form.NodeSelector',
name: 'nodename',
fieldLabel: 'Node',
fieldLabel: gettext('Node'),
allowBlank: false,
onlineValidator: true,
listeners: {
......@@ -105,7 +105,7 @@ Ext.define('PVE.openvz.CreateWizard', {
inputType: 'password',
name: 'password',
value: '',
fieldLabel: 'Password',
fieldLabel: gettext('Password'),
allowBlank: false,
minLength: 5,
change: function(f, value) {
......@@ -120,7 +120,7 @@ Ext.define('PVE.openvz.CreateWizard', {
inputType: 'password',
name: 'confirmpw',
value: '',
fieldLabel: 'Confirm password',
fieldLabel: gettext('Confirm password'),
allowBlank: false,
validator: function(value) {
var pw = me.down('field[name=password]').getValue();
......@@ -141,16 +141,16 @@ Ext.define('PVE.openvz.CreateWizard', {
},
{
xtype: 'inputpanel',
title: 'Template',
title: gettext('Template'),
column1: [ tmplstoragesel, tmplsel]
},
{
xtype: 'pveOpenVZResourceInputPanel',
title: 'Resources'
title: gettext('Resources')
},
{
xtype: 'inputpanel',
title: 'Network',
title: gettext('Network'),
column1: [
{
xtype: 'radiofield',
......@@ -173,7 +173,7 @@ Ext.define('PVE.openvz.CreateWizard', {
name: 'ip_address',
vtype: 'IPAddress',
value: '',
fieldLabel: 'IP address',
fieldLabel: gettext('IP address'),
labelAlign: 'right',
allowBlank: false
}
......@@ -251,11 +251,11 @@ Ext.define('PVE.openvz.CreateWizard', {
]
},
{
title: 'Confirm',
title: gettext('Confirm'),
layout: 'fit',
items: [
{
title: 'Settings',
title: gettext('Settings'),
xtype: 'grid',
store: summarystore,
columns: [
......@@ -310,7 +310,7 @@ Ext.define('PVE.openvz.CreateWizard', {
me.close();
},
failure: function(response, opts) {
Ext.Msg.alert('Error', response.htmlStatus);
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
}
});
}
......
......@@ -24,7 +24,7 @@ Ext.define('PVE.openvz.DNS', {
header: 'Hostname',
editor: {
xtype: 'pveWindowEdit',
title: 'Container Hostname',
subject: 'Hostname',
items: {
xtype: 'textfield',
name: 'hostname',
......@@ -40,7 +40,7 @@ Ext.define('PVE.openvz.DNS', {
defaultValue: '',
editor: {
xtype: 'pveWindowEdit',
title: 'DNS domain',
subject: 'DNS domain',
items: {
xtype: 'pvetextfield',
name: 'searchdomain',
......@@ -54,7 +54,7 @@ Ext.define('PVE.openvz.DNS', {
defaultValue: '',
editor: {
xtype: 'pveWindowEdit',
title: gettext('DNS server'),
subject: gettext('DNS server'),
items: {
xtype: 'pvetextfield',
name: 'nameserver',
......@@ -71,8 +71,9 @@ Ext.define('PVE.openvz.DNS', {
me.rstore.load();
};
var sm = Ext.create('Ext.selection.RowModel', {});
var run_editor = function() {
var sm = me.getSelectionModel();
var rec = sm.getSelection()[0];
if (!rec) {
return;
......@@ -95,9 +96,14 @@ Ext.define('PVE.openvz.DNS', {
win.on('destroy', reload);
};
var edit_btn = new Ext.Button({
text: 'Edit',
var edit_btn = new PVE.button.Button({
text: gettext('Edit'),
disabled: true,
selModel: sm,
enableFn: function(rec) {
var rowdef = rows[rec.data.key];
return !!rowdef.editor;
},
handler: run_editor
});
......@@ -115,6 +121,7 @@ Ext.define('PVE.openvz.DNS', {
Ext.applyIf(me, {
url: "/api2/json/nodes/" + nodename + "/openvz/" + vmid + "/config",
selModel: sm,
cwidth1: 150,
tbar: [ edit_btn ],
rows: rows,
......
......@@ -2,6 +2,8 @@
Ext.define('PVE.OpenVZ.NetIfEdit', {
extend: 'PVE.window.Edit',
isAdd: true,
getValues: function() {
var me = this;
......@@ -42,7 +44,7 @@ Ext.define('PVE.OpenVZ.NetIfEdit', {
}
Ext.apply(me, {
title: me.create ? 'Add ethernet device (veth)' : 'Edit ethernet device (veth)',
subject: gettext('Network Device') + ' (veth)',
digest: me.dataCache.digest,
width: 350,
fieldDefaults: {
......@@ -53,7 +55,7 @@ Ext.define('PVE.OpenVZ.NetIfEdit', {
xtype: me.create ? 'textfield' : 'displayfield',
name: 'ifname',
height: 22, // hack: set same height as text fields
fieldLabel: 'Device name',
fieldLabel: gettext('Name') + ' (i.e. eth0)',
allowBlank: false,
value: cdata.ifname,
validator: function(value) {
......@@ -66,7 +68,7 @@ Ext.define('PVE.OpenVZ.NetIfEdit', {
{
xtype: 'textfield',
name: 'mac',
fieldLabel: 'MAC address',
fieldLabel: 'MAC',
vtype: 'MacAddress',
value: cdata.mac,
allowBlank: me.create,
......@@ -107,6 +109,10 @@ Ext.define('PVE.OpenVZ.NetIfEdit', {
Ext.define('PVE.OpenVZ.IPAdd', {
extend: 'PVE.window.Edit',
isAdd: true,
create: true,
getValues: function() {
var me = this;
......@@ -128,13 +134,13 @@ Ext.define('PVE.OpenVZ.IPAdd', {
}
Ext.apply(me, {
title: "Add IP address (venet)",
subject: gettext('IP address') + ' (venet)',
digest: me.dataCache.digest,
width: 350,
items: {
xtype: 'textfield',
name: 'ipaddress',
fieldLabel: 'IP Address',
fieldLabel: gettext('IP address'),
vtype: 'IPAddress',
allowBlank: false
}
......@@ -151,13 +157,18 @@ Ext.define('PVE.openvz.NetworkView', {
dataCache: {}, // used to store result of last load
ipAddressText: gettext('IP address'),
networkText: gettext('Network'),
networkDeviceText: gettext('Network Device'),
renderType: function(value, metaData, record, rowIndex, colIndex, store) {
var me = this;
if (value === 'ip') {
return 'IP address';
return me.ipAddressText;
} else if (value === 'net') {
return 'IP network';
return me.networkText;
} else if (value === 'veth') {
return 'Ethernet device';
return me.networkDeviceText;
} else {
return value;
}
......@@ -180,7 +191,7 @@ Ext.define('PVE.openvz.NetworkView', {
PVE.Utils.API2Request({
url: me.url,
failure: function(response, opts) {
PVE.Utils.setErrorMask(me, 'Error: ' + response.htmlStatus);
PVE.Utils.setErrorMask(me, gettext('Error') + ': ' + response.htmlStatus);
},
success: function(response, opts) {
PVE.Utils.setErrorMask(me, false);
......@@ -237,67 +248,57 @@ Ext.define('PVE.openvz.NetworkView', {
model: 'pve-openvz-network'
});
var remove_btn = new Ext.Button({
text: 'Remove',
disabled: true,
handler: function(){
var sm = me.getSelectionModel();
var rec = sm.getSelection()[0];
var sm = Ext.create('Ext.selection.RowModel', {});
if (!rec) {
return;
var remove_btn = new PVE.button.Button({
text: gettext('Remove'),
disabled: true,
selModel: sm,
confirmMsg: function (rec) {
var idtext = rec.id;
if (rec.data.type === 'ip') {
idtext = rec.data.value;
} else if (rec.data.type === 'veth') {
idtext = rec.data.id;
}
return Ext.String.format(gettext('Are you sure you want to remove entry {0}'),
"'" + idtext + "'");
},
handler: function(btn, event, rec) {
var values = { digest: me.dataCache.digest };
var msg;
if (rec.data.type === 'ip') {
msg = 'Are you sure you want to remove IP address "' + rec.data.value + '"';
var ipa = [];
Ext.Array.each(me.dataCache.ip_address.split(' '), function(value) {
if (value && value !== rec.data.value) {
ipa.push(value);
}
});
values.ip_address = ipa.join(' ');
} else if (rec.data.type === 'veth') {
msg = 'Are you sure you want to remove device "' + rec.data.id + '"';
var netif = PVE.Parser.parseOpenVZNetIf(me.dataCache.netif);
delete netif[rec.data.id];
values.netif = PVE.Parser.printOpenVZNetIf(netif);
} else {
msg = 'Are you sure you want to remove this item';
return; // not implemented
}
Ext.Msg.confirm('Deletion Confirmation', msg, function(btn) {
if (btn !== 'yes') {
return;
}
var values = { digest: me.dataCache.digest };
if (rec.data.type === 'ip') {
var ipa = [];
Ext.Array.each(me.dataCache.ip_address.split(' '), function(value) {
if (value && value !== rec.data.value) {
ipa.push(value);
}
});
values.ip_address = ipa.join(' ');
} else if (rec.data.type === 'veth') {
var netif = PVE.Parser.parseOpenVZNetIf(me.dataCache.netif);
delete netif[rec.data.id];
values.netif = PVE.Parser.printOpenVZNetIf(netif);
} else {
return; // not implemented
PVE.Utils.API2Request({
url: me.url,
waitMsgTarget: me,
method: 'PUT',
params: values,
callback: function() {
me.load();
},
failure: function (response, opts) {
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
}
PVE.Utils.API2Request({
url: me.url,
waitMsgTarget: me,
method: 'PUT',
params: values,
callback: function() {
me.load();
},
failure: function (response, opts) {
Ext.Msg.alert('Error', response.htmlStatus);
}
});
});
}
});
var run_editor = function() {
var sm = me.getSelectionModel();
var rec = sm.getSelection()[0];
if (!rec || rec.data.type !== 'veth') {
return;
......@@ -313,37 +314,28 @@ Ext.define('PVE.openvz.NetworkView', {
win.show();
};
var edit_btn = new Ext.Button({
text: 'Edit',
var edit_btn = new PVE.button.Button({
text: gettext('Edit'),
selModel: sm,
disabled: true,
enableFn: function(rec) {
return rec.data.type === 'veth';
},
handler: run_editor
});
var set_button_status = function() {
var sm = me.getSelectionModel();
var rec = sm.getSelection()[0];
if (!rec) {
remove_btn.disable();
edit_btn.disable();
return;
}
edit_btn.setDisabled(rec.data.type !== 'veth');
remove_btn.setDisabled(false);
};
Ext.applyIf(me, {
store: store,
selModel: sm,
stateful: false,
//hideHeaders: true,
tbar: [
{
text: 'Add',
text: gettext('Add'),
menu: new Ext.menu.Menu({
items: [
{
text: 'IP address (venet)',
text: gettext('IP address') + ' (venet)',
//plain: true,
//iconCls: 'pve-itype-icon-storage',
handler: function() {
......@@ -356,7 +348,7 @@ Ext.define('PVE.openvz.NetworkView', {
}
},
{
text: 'Ethernet device (veth)',
text: gettext('Network Device') + ' (veth)',
//plain: true,
//iconCls: 'pve-itype-icon-storage',
handler: function() {
......@@ -378,13 +370,13 @@ Ext.define('PVE.openvz.NetworkView', {
],
columns: [
{
header: 'Type',
header: gettext('Type'),
width: 110,
dataIndex: 'type',
renderer: me.renderType
},
{
header: 'IP/Name',
header: gettext('IP address') +'/' + gettext('Name'),
width: 110,
dataIndex: 'value',
renderer: me.renderValue
......@@ -412,8 +404,7 @@ Ext.define('PVE.openvz.NetworkView', {
],
listeners: {
show: me.load,
itemdblclick: run_editor,
selectionchange: set_button_status
itemdblclick: run_editor
}
});
......
......@@ -19,27 +19,27 @@ Ext.define('PVE.openvz.Options', {
var rows = {
onboot: {
header: 'Start at boot',
header: gettext('Start at boot'),
defaultValue: '',
renderer: PVE.Utils.format_boolean,
editor: {
xtype: 'pveWindowEdit',
title: 'Start at boot',
subject: gettext('Start at boot'),
items: {
xtype: 'pvecheckbox',
name: 'onboot',
uncheckedValue: 0,
defaultValue: 0,
fieldLabel: 'Start at boot'
fieldLabel: gettext('Start at boot')
}
}
},
ostemplate: {
header: 'Template',
header: gettext('Template'),
defaultValue: 'no set'
},
storage: {
header: 'Storage',
header: gettext('Storage'),
defaultValue: 'no set'
},
cpuunits: {
......@@ -47,7 +47,7 @@ Ext.define('PVE.openvz.Options', {
defaultValue: '1000',
editor: {
xtype: 'pveWindowEdit',
title: 'CPU units',
subject: 'CPU units',
items: {
xtype: 'numberfield',
name: 'cpuunits',
......@@ -69,7 +69,7 @@ Ext.define('PVE.openvz.Options', {
},
editor: {
xtype: 'pveWindowEdit',
title: 'Quota UGID limit (0 to disable user quotas)',
subject: 'Quota UGID limit (0 to disable user quotas)',
items: {
xtype: 'numberfield',
name: 'quotaugidlimit',
......@@ -84,7 +84,7 @@ Ext.define('PVE.openvz.Options', {
defaultValue: '0',
editor: {
xtype: 'pveWindowEdit',
title: 'Quota Grace period (seconds)',
subject: 'Quota Grace period (seconds)',
items: {
xtype: 'numberfield',
name: 'quotatime',
......@@ -102,8 +102,9 @@ Ext.define('PVE.openvz.Options', {
me.rstore.load();
};
var sm = Ext.create('Ext.selection.RowModel', {});
var run_editor = function() {
var sm = me.getSelectionModel();
var rec = sm.getSelection()[0];
if (!rec) {
return;
......@@ -126,32 +127,25 @@ Ext.define('PVE.openvz.Options', {
win.on('destroy', reload);
};
var edit_btn = new Ext.Button({
text: 'Edit',
var edit_btn = new PVE.button.Button({
text: gettext('Edit'),
disabled: true,
selModel: sm,
enableFn: function(rec) {
var rowdef = rows[rec.data.key];
return !!rowdef.editor;
},
handler: run_editor
});
var set_button_status = function() {
var sm = me.getSelectionModel();
var rec = sm.getSelection()[0];
if (!rec) {
edit_btn.disable();
return;
}
var rowdef = rows[rec.data.key];
edit_btn.setDisabled(!rowdef.editor);
};
Ext.applyIf(me, {
url: "/api2/json/nodes/" + nodename + "/openvz/" + vmid + "/config",
selModel: sm,
cwidth1: 150,
tbar: [ edit_btn ],
rows: rows,
listeners: {
itemdblclick: run_editor,
selectionchange: set_button_status
itemdblclick: run_editor
}
});
......
......@@ -7,6 +7,8 @@ Ext.define('PVE.openvz.RessourceInputPanel', {
initComponent : function() {
var me = this;
var labelWidth = 120;
me.column1 = [
{
xtype: 'numberfield',
......@@ -15,7 +17,8 @@ Ext.define('PVE.openvz.RessourceInputPanel', {
maxValue: 128*1024,
value: '512',
step: 32,
fieldLabel: 'Memory (MB)',
fieldLabel: gettext('Memory') + ' (MB)',
labelWidth: labelWidth,
allowBlank: false
},
{
......@@ -25,7 +28,8 @@ Ext.define('PVE.openvz.RessourceInputPanel', {
maxValue: 128*1024,
value: '512',
step: 32,
fieldLabel: 'Swap (MB)',
fieldLabel: gettext('Swap') + ' (MB)',
labelWidth: labelWidth,
allowBlank: false
}
];
......@@ -37,7 +41,8 @@ Ext.define('PVE.openvz.RessourceInputPanel', {
minValue: 0.5,
value: '4',
step: 1,
fieldLabel: 'Disk space (GB)',
fieldLabel: gettext('Disk size') + ' (GB)',
labelWidth: labelWidth,
allowBlank: false
},
{
......@@ -47,6 +52,7 @@ Ext.define('PVE.openvz.RessourceInputPanel', {
value: '1',
step: 1,
fieldLabel: 'CPUs',
labelWidth: labelWidth,
allowBlank: false
}
];
......@@ -62,7 +68,7 @@ Ext.define('PVE.openvz.RessourceEdit', {
var me = this;
Ext.apply(me, {
title: "Edit ressource settings",
subject: gettext('Resources'),
items: Ext.create('PVE.openvz.RessourceInputPanel')
});
......
......@@ -20,7 +20,7 @@ Ext.define('PVE.openvz.RessourceView', {
var rows = {
memory: {
header: 'Memory',
header: gettext('Memory'),
editor: 'PVE.openvz.RessourceEdit',
never_delete: true,
renderer: function(value) {
......@@ -28,7 +28,7 @@ Ext.define('PVE.openvz.RessourceView', {
}
},
swap: {
header: 'Swap',
header: gettext('Swap'),
editor: 'PVE.openvz.RessourceEdit',
never_delete: true,
renderer: function(value) {
......@@ -36,13 +36,13 @@ Ext.define('PVE.openvz.RessourceView', {
}
},
cpus: {
header: 'Processors',
header: gettext('Processors'),
never_delete: true,
editor: 'PVE.openvz.RessourceEdit',
defaultValue: 1
},
disk: {
header: 'Disk space',
header: gettext('Disk size'),
editor: 'PVE.openvz.RessourceEdit',
never_delete: true,
renderer: function(value) {
......@@ -57,8 +57,9 @@ Ext.define('PVE.openvz.RessourceView', {
var baseurl = 'nodes/' + nodename + '/openvz/' + vmid + '/config';
var sm = Ext.create('Ext.selection.RowModel', {});
var run_editor = function() {
var sm = me.getSelectionModel();
var rec = sm.getSelection()[0];
if (!rec) {
return;
......@@ -81,36 +82,29 @@ Ext.define('PVE.openvz.RessourceView', {
win.on('destroy', reload);
};
var edit_btn = new Ext.Button({
text: 'Edit',
var edit_btn = new PVE.button.Button({
text: gettext('Edit'),
selModel: sm,
disabled: true,
enableFn: function(rec) {
if (!rec) {
return false;
}
var rowdef = rows[rec.data.key];
return !!rowdef.editor;
},
handler: run_editor
});
var set_button_status = function() {
var sm = me.getSelectionModel();
var rec = sm.getSelection()[0];
if (!rec) {
edit_btn.disable();
return;
}
var rowdef = rows[rec.data.key];
edit_btn.setDisabled(!rowdef.editor);
};
Ext.applyIf(me, {
url: '/api2/json/' + baseurl,
selModel: sm,
cwidth1: 170,
tbar: [ edit_btn ],
rows: rows,
listeners: {
show: reload,
itemdblclick: run_editor,
selectionchange: set_button_status
itemdblclick: run_editor
}
});
......
......@@ -19,19 +19,19 @@ Ext.define('PVE.qemu.CreateWizard', {
});
var cdpanel = Ext.create('PVE.qemu.CDInputPanel', {
title: 'Installation Media',
title: 'CD/DVD',
confid: 'ide2',
insideWizard: true
});
var hdpanel = Ext.create('PVE.qemu.HDInputPanel', {
title: 'Harddisk',
title: gettext('Hard Disk'),
create: true,
insideWizard: true
});
var networkpanel = Ext.create('PVE.qemu.NetworkInputPanel', {
title: 'Network',
title: gettext('Network'),
insideWizard: true
});
......@@ -40,12 +40,12 @@ Ext.define('PVE.qemu.CreateWizard', {
items: [
{
xtype: 'inputpanel',
title: 'General',
title: gettext('General'),
column1: [
{
xtype: 'PVE.form.NodeSelector',
name: 'nodename',
fieldLabel: 'Node',
fieldLabel: gettext('Node'),
allowBlank: false,
onlineValidator: true,
listeners: {
......@@ -66,7 +66,7 @@ Ext.define('PVE.qemu.CreateWizard', {
xtype: 'textfield',
name: 'name',
value: '',
fieldLabel: 'VM name',
fieldLabel: gettext('Name'),
allowBlank: true
}
],
......@@ -90,7 +90,7 @@ Ext.define('PVE.qemu.CreateWizard', {
}
},
{
title: 'OS Type',
title: 'OS',
xtype: 'PVE.qemu.OSTypeInputPanel'
},
cdpanel,
......@@ -102,15 +102,15 @@ Ext.define('PVE.qemu.CreateWizard', {
{
xtype: 'PVE.qemu.MemoryInputPanel',
insideWizard: true,
title: 'Memory'
title: gettext('Memory')
},
networkpanel,
{
title: 'Confirm',
title: gettext('Confirm'),
layout: 'fit',
items: [
{
title: 'Settings',
title: gettext('Settings'),
xtype: 'grid',
store: summarystore,
columns: [
......@@ -156,7 +156,7 @@ Ext.define('PVE.qemu.CreateWizard', {
me.close();
},
failure: function(response, opts) {
Ext.Msg.alert('Error', response.htmlStatus);
Ext.Msg.alert(gettext('Error'), response.htmlStatus);
}
});
}
......
......@@ -7,6 +7,8 @@ Ext.define('PVE.qemu.MemoryInputPanel', {
initComponent : function() {
var me = this;
var labelWidth = 120;
var items = {
xtype: 'numberfield',
name: 'memory',
......@@ -15,6 +17,7 @@ Ext.define('PVE.qemu.MemoryInputPanel', {
value: '512',
step: 32,
fieldLabel: gettext('Memory') + ' (MB)',
labelWidth: labelWidth,
allowBlank: false
};
......@@ -36,7 +39,6 @@ Ext.define('PVE.qemu.MemoryEdit', {
Ext.apply(me, {
subject: gettext('Memory'),
fieldDefaults: { labelWidth: 120 },
items: Ext.create('PVE.qemu.MemoryInputPanel')
});
......
......@@ -35,19 +35,19 @@ Ext.define('PVE.qemu.Options', {
}
},
onboot: {
header: 'Start at boot',
header: gettext('Start at boot'),
defaultValue: '',
renderer: PVE.Utils.format_boolean,
editor: {
xtype: 'pveWindowEdit',
subject: 'Start at boot',
subject: gettext('Start at boot'),
items: {
xtype: 'pvecheckbox',
name: 'onboot',
uncheckedValue: 0,
defaultValue: 0,
deleteDefaultValue: true,
fieldLabel: 'Start at boot'
fieldLabel: gettext('Start at boot')
}
}
},
......
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