diff --git a/.eslintrc b/.eslintrc
index b2313ee0c4..c5e7d6831a 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -12,6 +12,7 @@
"indent": "off",
"brace-style": "off",
"no-mixed-spaces-and-tabs": "off",
+ "no-useless-escape": "off",
"space-unary-ops": ["error", { "words": true }],
"linebreak-style": "off",
"quotes": ["off"],
@@ -21,15 +22,12 @@
"no-console": ["warn"],
"no-extra-boolean-cast": ["off"],
"no-control-regex": ["off"],
- "space-before-blocks": "warn",
- "keyword-spacing": "warn",
- "comma-spacing": "warn",
- "key-spacing": "warn"
},
"root": true,
"globals": {
"frappe": true,
"Vue": true,
+ "SetVueGlobals": true,
"__": true,
"repl": true,
"Class": true,
@@ -45,8 +43,10 @@
"is_null": true,
"in_list": true,
"has_common": true,
+ "posthog": true,
"has_words": true,
"validate_email": true,
+ "open_web_template_values_editor": true,
"validate_name": true,
"validate_phone": true,
"validate_url": true,
diff --git a/frappe/core/doctype/user/user.js b/frappe/core/doctype/user/user.js
index e389a73cbb..7a72918f35 100644
--- a/frappe/core/doctype/user/user.js
+++ b/frappe/core/doctype/user/user.js
@@ -271,7 +271,7 @@ frappe.ui.form.on("User", {
if (frappe.route_flags.unsaved === 1) {
delete frappe.route_flags.unsaved;
- for (var i = 0; i < frm.doc.user_emails.length; i++) {
+ for (let i = 0; i < frm.doc.user_emails.length; i++) {
frm.doc.user_emails[i].idx = frm.doc.user_emails[i].idx + 1;
}
frm.dirty();
@@ -308,7 +308,7 @@ frappe.ui.form.on("User", {
enable_incoming: 1,
};
frappe.model.with_doctype("Email Account", function (doc) {
- var doc = frappe.model.get_new_doc("Email Account");
+ doc = frappe.model.get_new_doc("Email Account");
frappe.route_flags.linked_user = frm.doc.name;
frappe.route_flags.delete_user_from_locals = true;
frappe.set_route("Form", "Email Account", doc.name);
diff --git a/frappe/custom/doctype/doctype_layout/doctype_layout.js b/frappe/custom/doctype/doctype_layout/doctype_layout.js
index b212b79a5b..9c803e40f6 100644
--- a/frappe/custom/doctype/doctype_layout/doctype_layout.js
+++ b/frappe/custom/doctype/doctype_layout/doctype_layout.js
@@ -31,7 +31,7 @@ frappe.ui.form.on("DocType Layout", {
await frm.events.sync_fields(frm, false);
if (frm.is_new()) {
- frm.doc.__newname = document_name;
+ frm.doc.__newname = document_name; // eslint-disable-line
frm.refresh_field("__newname");
}
}
diff --git a/frappe/desk/page/setup_wizard/setup_wizard.js b/frappe/desk/page/setup_wizard/setup_wizard.js
index e5c268b24c..decf540097 100644
--- a/frappe/desk/page/setup_wizard/setup_wizard.js
+++ b/frappe/desk/page/setup_wizard/setup_wizard.js
@@ -642,7 +642,7 @@ function guess_country(country_info) {
try {
const system_timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
- for ([country, info] of Object.entries(country_info)) {
+ for (let [country, info] of Object.entries(country_info)) {
let possible_timezones = (info.timezones || []).filter((t) => t == system_timezone);
if (possible_timezones.length) return country;
}
diff --git a/frappe/printing/page/print_format_builder/print_format_builder.js b/frappe/printing/page/print_format_builder/print_format_builder.js
index 657904f32e..46313ef992 100644
--- a/frappe/printing/page/print_format_builder/print_format_builder.js
+++ b/frappe/printing/page/print_format_builder/print_format_builder.js
@@ -372,10 +372,11 @@ frappe.PrintFormatBuilder = class PrintFormatBuilder {
if (!$item.hasClass("print-format-builder-field")) {
var fieldname = $item.attr("data-fieldname");
+ let field;
if (fieldname === "_custom_html") {
- var field = me.get_custom_html_field();
+ field = me.get_custom_html_field();
} else {
- var field = frappe.meta.get_docfield(me.print_format.doc_type, fieldname);
+ field = frappe.meta.get_docfield(me.print_format.doc_type, fieldname);
}
var html = frappe.render_template("print_format_builder_field", {
@@ -561,7 +562,7 @@ frappe.PrintFormatBuilder = class PrintFormatBuilder {
resize();
} else if (new_no_of_columns > no_of_columns) {
// add empty column and resize old columns
- for (var i = no_of_columns; i < new_no_of_columns; i++) {
+ for (let i = no_of_columns; i < new_no_of_columns; i++) {
var col = $(
'
'
diff --git a/frappe/public/js/frappe/defaults.js b/frappe/public/js/frappe/defaults.js
index a96f6c3167..fa92ef45f0 100644
--- a/frappe/public/js/frappe/defaults.js
+++ b/frappe/public/js/frappe/defaults.js
@@ -8,7 +8,7 @@ frappe.defaults = {
if (!d && frappe.defaults.is_a_user_permission_key(key)) {
d = defaults[frappe.model.scrub(key)];
// Check for default user permission values
- user_default = this.get_user_permission_default(key, defaults);
+ let user_default = this.get_user_permission_default(key, defaults);
if (user_default) d = user_default;
}
if ($.isArray(d)) d = d[0];
diff --git a/frappe/public/js/frappe/form/grid.js b/frappe/public/js/frappe/form/grid.js
index 69378d3c30..77072d0141 100644
--- a/frappe/public/js/frappe/form/grid.js
+++ b/frappe/public/js/frappe/form/grid.js
@@ -441,12 +441,13 @@ export default class Grid {
if (d.name === undefined) {
d.name = "row " + d.idx;
}
+ let grid_row;
if (this.grid_rows[ri] && !append_row) {
- var grid_row = this.grid_rows[ri];
+ grid_row = this.grid_rows[ri];
grid_row.doc = d;
grid_row.refresh();
} else {
- var grid_row = new GridRow({
+ grid_row = new GridRow({
parent: $rows,
parent_df: this.df,
docfields: this.docfields,
diff --git a/frappe/public/js/frappe/form/save.js b/frappe/public/js/frappe/form/save.js
index 2dffdcf863..667bfc4664 100644
--- a/frappe/public/js/frappe/form/save.js
+++ b/frappe/public/js/frappe/form/save.js
@@ -156,6 +156,7 @@ frappe.ui.form.save = function (frm, action, callback, btn) {
if (error_fields.length) {
let meta = frappe.get_meta(doc.doctype);
+ let message;
if (meta.istable) {
const table_field = frappe.meta.docfield_map[doc.parenttype][doc.parentfield];
@@ -163,12 +164,12 @@ frappe.ui.form.save = function (frm, action, callback, btn) {
table_field.label || frappe.unscrub(table_field.fieldname)
).bold();
- var message = __("Mandatory fields required in table {0}, Row {1}", [
+ message = __("Mandatory fields required in table {0}, Row {1}", [
table_label,
doc.idx,
]);
} else {
- var message = __("Mandatory fields required in {0}", [__(doc.doctype)]);
+ message = __("Mandatory fields required in {0}", [__(doc.doctype)]);
}
message = message + "
- " + error_fields.join("
- ") + "
";
frappe.msgprint({
diff --git a/frappe/public/js/frappe/form/toolbar.js b/frappe/public/js/frappe/form/toolbar.js
index 60b90fe9db..e6c24e304c 100644
--- a/frappe/public/js/frappe/form/toolbar.js
+++ b/frappe/public/js/frappe/form/toolbar.js
@@ -31,11 +31,12 @@ frappe.ui.form.Toolbar = class Toolbar {
}
}
set_title() {
+ let title;
if (this.frm.is_new()) {
- var title = __("New {0}", [__(this.frm.meta.name)]);
+ title = __("New {0}", [__(this.frm.meta.name)]);
} else if (this.frm.meta.title_field) {
let title_field = (this.frm.doc[this.frm.meta.title_field] || "").toString().trim();
- var title = strip_html(title_field || this.frm.docname);
+ title = strip_html(title_field || this.frm.docname);
if (
this.frm.doc.__islocal ||
title === this.frm.docname ||
@@ -51,7 +52,7 @@ frappe.ui.form.Toolbar = class Toolbar {
});
}
} else {
- var title = this.frm.docname;
+ title = this.frm.docname;
}
var me = this;
diff --git a/frappe/public/js/frappe/microtemplate.js b/frappe/public/js/frappe/microtemplate.js
index 4e0bd76601..f3041c677a 100644
--- a/frappe/public/js/frappe/microtemplate.js
+++ b/frappe/public/js/frappe/microtemplate.js
@@ -2,6 +2,8 @@
// Adapted from John Resig - http://ejohn.org/ - MIT Licensed
frappe.template = { compiled: {}, debug: {} };
+
+/* eslint-disable */
frappe.template.compile = function (str, name) {
var key = name || str;
@@ -96,14 +98,17 @@ frappe.template.compile = function (str, name) {
return frappe.template.compiled[key];
};
+/* eslint-enable */
+
frappe.render = function (str, data, name) {
return frappe.template.compile(str, name)(data);
};
frappe.render_template = function (name, data) {
+ let template;
if (name.indexOf(" ") !== -1) {
- var template = name;
+ template = name;
} else {
- var template = frappe.templates[name];
+ template = frappe.templates[name];
}
if (data === undefined) {
data = {};
diff --git a/frappe/public/js/frappe/model/indicator.js b/frappe/public/js/frappe/model/indicator.js
index 4413020391..d5c42c3799 100644
--- a/frappe/public/js/frappe/model/indicator.js
+++ b/frappe/public/js/frappe/model/indicator.js
@@ -43,10 +43,10 @@ frappe.get_indicator = function (doc, doctype, show_workflow_state) {
if (workflow_fieldname && (!without_workflow || show_workflow_state)) {
var value = doc[workflow_fieldname];
if (value) {
- var colour = "";
+ let colour = "";
if (locals["Workflow State"][value] && locals["Workflow State"][value].style) {
- var colour = {
+ colour = {
Success: "green",
Warning: "orange",
Danger: "red",
diff --git a/frappe/public/js/frappe/model/model.js b/frappe/public/js/frappe/model/model.js
index 355e0a9c5d..0802d8b34c 100644
--- a/frappe/public/js/frappe/model/model.js
+++ b/frappe/public/js/frappe/model/model.js
@@ -462,8 +462,9 @@ $.extend(frappe.model, {
var val = locals[dt] && locals[dt][dn] && locals[dt][dn][fn];
var df = frappe.meta.get_docfield(dt, fn, dn);
+ let ret;
if (frappe.model.table_fields.includes(df.fieldtype)) {
- var ret = false;
+ ret = false;
$.each(locals[df.options] || {}, function (k, d) {
if (d.parent == dn && d.parenttype == dt && d.parentfield == df.fieldname) {
ret = true;
@@ -471,7 +472,7 @@ $.extend(frappe.model, {
}
});
} else {
- var ret = !is_null(val);
+ ret = !is_null(val);
}
return ret ? true : false;
},
@@ -616,12 +617,13 @@ $.extend(frappe.model, {
},
get_children: function (doctype, parent, parentfield, filters) {
+ let doc;
if ($.isPlainObject(doctype)) {
- var doc = doctype;
- var filters = parentfield;
- var parentfield = parent;
+ doc = doctype;
+ filters = parentfield;
+ parentfield = parent;
} else {
- var doc = frappe.get_doc(doctype, parent);
+ doc = frappe.get_doc(doctype, parent);
}
var children = doc[parentfield] || [];
@@ -652,8 +654,8 @@ $.extend(frappe.model, {
var parent = null;
if (doc.parenttype) {
- var parent = doc.parent,
- parenttype = doc.parenttype,
+ parent = doc.parent;
+ var parenttype = doc.parenttype,
parentfield = doc.parentfield;
}
delete locals[doctype][name];
diff --git a/frappe/public/js/frappe/request.js b/frappe/public/js/frappe/request.js
index 69867a6b14..9693b8f41f 100644
--- a/frappe/public/js/frappe/request.js
+++ b/frappe/public/js/frappe/request.js
@@ -304,7 +304,7 @@ frappe.request.call = function (opts) {
data = JSON.parse(data);
}
if (data.responseText) {
- var xhr = data;
+ var xhr = data; // eslint-disable-line
data = JSON.parse(data.responseText);
}
} catch (e) {
diff --git a/frappe/public/js/frappe/ui/messages.js b/frappe/public/js/frappe/ui/messages.js
index 16096e1845..b8ed34d59d 100644
--- a/frappe/public/js/frappe/ui/messages.js
+++ b/frappe/public/js/frappe/ui/messages.js
@@ -111,14 +111,15 @@ frappe.prompt = function (fields, callback, title, primary_label) {
frappe.msgprint = function (msg, title, is_minimizable) {
if (!msg) return;
+ let data;
if ($.isPlainObject(msg)) {
- var data = msg;
+ data = msg;
} else {
// passed as JSON
if (typeof msg === "string" && msg.substr(0, 1) === "{") {
- var data = JSON.parse(msg);
+ data = JSON.parse(msg);
} else {
- var data = { message: msg, title: title };
+ data = { message: msg, title: title };
}
}
diff --git a/frappe/public/js/frappe/ui/toolbar/about.js b/frappe/public/js/frappe/ui/toolbar/about.js
index b75f950d72..28cafd202a 100644
--- a/frappe/public/js/frappe/ui/toolbar/about.js
+++ b/frappe/public/js/frappe/ui/toolbar/about.js
@@ -50,14 +50,15 @@ frappe.ui.misc.about = function () {
var $wrap = $("#about-app-versions").empty();
$.each(Object.keys(versions).sort(), function (i, key) {
var v = versions[key];
+ let text;
if (v.branch) {
- var text = $.format("{0}: v{1} ({2})
", [
+ text = $.format("{0}: v{1} ({2})
", [
v.title,
v.branch_version || v.version,
v.branch,
]);
} else {
- var text = $.format("{0}: v{1}
", [v.title, v.version]);
+ text = $.format("{0}: v{1}
", [v.title, v.version]);
}
$(text).appendTo($wrap);
});
diff --git a/frappe/public/js/frappe/ui/toolbar/search_utils.js b/frappe/public/js/frappe/ui/toolbar/search_utils.js
index 434fb888fc..0f514eb965 100644
--- a/frappe/public/js/frappe/ui/toolbar/search_utils.js
+++ b/frappe/public/js/frappe/ui/toolbar/search_utils.js
@@ -360,12 +360,13 @@ frappe.search.utils = {
var part = parts[i];
if (part.toLowerCase().indexOf(keywords) !== -1) {
// If the field contains the keyword
+ let colon_index, field_value;
if (part.indexOf(" &&& ") !== -1) {
- var colon_index = part.indexOf(" &&& ");
- var field_value = part.slice(colon_index + 5);
+ colon_index = part.indexOf(" &&& ");
+ field_value = part.slice(colon_index + 5);
} else {
- var colon_index = part.indexOf(" : ");
- var field_value = part.slice(colon_index + 3);
+ colon_index = part.indexOf(" : ");
+ field_value = part.slice(colon_index + 3);
}
if (field_value.length > field_length) {
// If field value exceeds field_length, find the keyword in it
diff --git a/frappe/public/js/frappe/ui/toolbar/toolbar.js b/frappe/public/js/frappe/ui/toolbar/toolbar.js
index 64a69cb947..d95c2f4a5b 100644
--- a/frappe/public/js/frappe/ui/toolbar/toolbar.js
+++ b/frappe/public/js/frappe/ui/toolbar/toolbar.js
@@ -82,7 +82,7 @@ frappe.ui.toolbar.Toolbar = class {
var breadcrumbs = route.split("/");
var links = [];
- for (var i = 0; i < breadcrumbs.length; i++) {
+ for (let i = 0; i < breadcrumbs.length; i++) {
var r = route.split("/", i + 1);
var key = r.join("/");
var help_links = frappe.help.help_links[key] || [];
@@ -95,7 +95,7 @@ frappe.ui.toolbar.Toolbar = class {
$help_links.next().show();
}
- for (var i = 0; i < links.length; i++) {
+ for (let i = 0; i < links.length; i++) {
var link = links[i];
var url = link.url;
$("", {
diff --git a/frappe/public/js/frappe/utils/number_format.js b/frappe/public/js/frappe/utils/number_format.js
index ef4c7366f7..649353f654 100644
--- a/frappe/public/js/frappe/utils/number_format.js
+++ b/frappe/public/js/frappe/utils/number_format.js
@@ -252,10 +252,11 @@ function in_list(list, item) {
function remainder(numerator, denominator, precision) {
precision = cint(precision);
var multiplier = Math.pow(10, precision);
+ let _remainder;
if (precision) {
- var _remainder = ((numerator * multiplier) % (denominator * multiplier)) / multiplier;
+ _remainder = ((numerator * multiplier) % (denominator * multiplier)) / multiplier;
} else {
- var _remainder = numerator % denominator;
+ _remainder = numerator % denominator;
}
return flt(_remainder, precision);
diff --git a/frappe/public/js/frappe/utils/user.js b/frappe/public/js/frappe/utils/user.js
index c922131a98..6a0221b1a2 100644
--- a/frappe/public/js/frappe/utils/user.js
+++ b/frappe/public/js/frappe/utils/user.js
@@ -1,10 +1,11 @@
frappe.user_info = function (uid) {
if (!uid) uid = frappe.session.user;
+ let user_info;
if (!(frappe.boot.user_info && frappe.boot.user_info[uid])) {
- var user_info = { fullname: uid || "Unknown" };
+ user_info = { fullname: uid || "Unknown" };
} else {
- var user_info = frappe.boot.user_info[uid];
+ user_info = frappe.boot.user_info[uid];
}
user_info.abbr = frappe.get_abbr(user_info.fullname);
diff --git a/frappe/public/js/frappe/utils/utils.js b/frappe/public/js/frappe/utils/utils.js
index 7c4bbbf2da..3133d70188 100644
--- a/frappe/public/js/frappe/utils/utils.js
+++ b/frappe/public/js/frappe/utils/utils.js
@@ -481,7 +481,7 @@ Object.assign(frappe.utils, {
break;
case "url":
regExp =
- /^((([A-Za-z0-9.+-]+:(?:\/\/)?)(?:[-;:&=\+\,\w]@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/i;
+ /^((([A-Za-z0-9.+-]+:(?:\/\/)?)(?:[-;:&=\+\,\w]@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/i; // eslint-disable-line
break;
case "dateIso":
regExp = /^(\d{4})\D?(0[1-9]|1[0-2])\D?([12]\d|0[1-9]|3[01])$/;
diff --git a/frappe/public/js/frappe/views/container.js b/frappe/public/js/frappe/views/container.js
index e4bd4a4def..88718a2094 100644
--- a/frappe/public/js/frappe/views/container.js
+++ b/frappe/public/js/frappe/views/container.js
@@ -41,11 +41,12 @@ frappe.views.Container = class Container {
}
change_to(label) {
cur_page = this;
+ let page;
if (label.tagName) {
// if sent the div, get the table
- var page = label;
+ page = label;
} else {
- var page = frappe.pages[label];
+ page = frappe.pages[label];
}
if (!page) {
console.log(__("Page not found") + ": " + label);
diff --git a/frappe/public/js/frappe/views/reports/report_utils.js b/frappe/public/js/frappe/views/reports/report_utils.js
index 16b02c28a1..869d7d5584 100644
--- a/frappe/public/js/frappe/views/reports/report_utils.js
+++ b/frappe/public/js/frappe/views/reports/report_utils.js
@@ -235,7 +235,7 @@ frappe.report_utils = {
const is_query_report = frappe.get_route()[0] === "query-report";
const report = is_query_report ? frappe.query_report : cur_list;
const columns = report.columns.filter((col) => col.hidden !== 1);
- PREVIEW_DATA = [
+ let PREVIEW_DATA = [
columns.map((col) => __(is_query_report ? col.label : col.name)),
...report.data
.slice(0, 3)
diff --git a/frappe/public/js/onboarding_tours/onboarding_tours.js b/frappe/public/js/onboarding_tours/onboarding_tours.js
index 29790ce5de..462d364fe9 100644
--- a/frappe/public/js/onboarding_tours/onboarding_tours.js
+++ b/frappe/public/js/onboarding_tours/onboarding_tours.js
@@ -275,7 +275,7 @@ frappe.ui.init_onboarding_tour = () => {
frappe.boot.onboarding_tours &&
frappe.boot.onboarding_tours.forEach((tour) => {
let tour_route = tour[1];
- length = Math.min(route.length, tour_route.length);
+ let length = Math.min(route.length, tour_route.length);
if (length >= 1 && route[0] != tour_route[0]) return;
if (length >= 2 && tour_route[1] != "*" && route[1] != tour_route[1]) return;
if (
diff --git a/frappe/website/js/website.js b/frappe/website/js/website.js
index 13f6390e97..62272f5f0c 100644
--- a/frappe/website/js/website.js
+++ b/frappe/website/js/website.js
@@ -563,14 +563,14 @@ frappe.setup_search = function (target, search_scope) {
// Utility functions
window.valid_email = function (id) {
- // eslint-disable-next-line
// copied regex from frappe/utils.js validate_type
+ // eslint-disable-next-line
return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/.test(
id.toLowerCase()
);
};
-window.validate_email = valid_email;
+window.validate_email = window.valid_email;
window.cstr = function (s) {
return s == null ? "" : s + "";
diff --git a/frappe/workflow/doctype/workflow/workflow.js b/frappe/workflow/doctype/workflow/workflow.js
index 12306725a1..91a71f5ac1 100644
--- a/frappe/workflow/doctype/workflow/workflow.js
+++ b/frappe/workflow/doctype/workflow/workflow.js
@@ -8,7 +8,7 @@ frappe.ui.form.on("Workflow", {
frm.layout.message.empty();
let title, note;
let workflow_builder_url = "/app/workflow-builder";
- msg = __(
+ let msg = __(
"Workflow Builder allows you to create workflows visually. You can drag and drop states and link them to create transitions. Also you can update thieir properties from the sidebar."
);