diff options
Diffstat (limited to 'editor')
23 files changed, 83 insertions, 70 deletions
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp index e08f2fcf65..0d89f37dd2 100644 --- a/editor/action_map_editor.cpp +++ b/editor/action_map_editor.cpp @@ -254,6 +254,7 @@ Variant ActionMapEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from Label *label = memnew(Label(name)); label->set_theme_type_variation("HeaderSmall"); label->set_modulate(Color(1, 1, 1, 1.0f)); + label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); action_tree->set_drag_preview(label); Dictionary drag_data; diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 66ebd07c2a..2e8c727849 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -1443,6 +1443,11 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { i++; } + AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton(); + if (ape) { + undo_redo->add_do_method(ape, "_animation_update_key_frame"); + undo_redo->add_undo_method(ape, "_animation_update_key_frame"); + } undo_redo->commit_action(); } else if (select_single_attempt != IntPair(-1, -1)) { @@ -1967,15 +1972,6 @@ void AnimationBezierTrackEdit::delete_selection() { void AnimationBezierTrackEdit::_bezier_track_insert_key_at_anim(const Ref<Animation> &p_anim, int p_track, double p_time, real_t p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle, const Animation::HandleMode p_handle_mode) { int idx = p_anim->bezier_track_insert_key(p_track, p_time, p_value, p_in_handle, p_out_handle); p_anim->bezier_track_set_key_handle_mode(p_track, idx, p_handle_mode); - - EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Animation Bezier Curve Change Call")); - AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton(); - if (ape) { - undo_redo->add_do_method(ape, "_animation_update_key_frame"); - undo_redo->add_undo_method(ape, "_animation_update_key_frame"); - } - undo_redo->commit_action(); } void AnimationBezierTrackEdit::_bind_methods() { diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 07b7c34a10..d277ba2f6d 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -3241,6 +3241,7 @@ Variant AnimationTrackEdit::get_drag_data(const Point2 &p_point) { tb->set_flat(true); tb->set_text(path_cache); tb->set_icon(icon_cache); + tb->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); tb->add_theme_constant_override("icon_max_width", get_theme_constant("class_icon_size", EditorStringName(Editor))); set_drag_preview(tb); diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 42346a0c0b..330ac3b437 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -615,6 +615,7 @@ Variant CreateDialog::get_drag_data_fw(const Point2 &p_point, Control *p_from) { tb->set_flat(true); tb->set_icon(ti->get_icon(0)); tb->set_text(ti->get_text(0)); + tb->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); favorites->set_drag_preview(tb); return d; diff --git a/editor/directory_create_dialog.cpp b/editor/directory_create_dialog.cpp index 604531f109..46baa2c6e1 100644 --- a/editor/directory_create_dialog.cpp +++ b/editor/directory_create_dialog.cpp @@ -31,6 +31,7 @@ #include "directory_create_dialog.h" #include "core/io/dir_access.h" +#include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/gui/editor_validation_panel.h" #include "editor/themes/editor_scale.h" @@ -100,15 +101,7 @@ void DirectoryCreateDialog::ok_pressed() { const String error = _validate_path(path); ERR_FAIL_COND_MSG(!error.is_empty(), error); - Error err; - Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - - err = da->change_dir(base_dir); - ERR_FAIL_COND_MSG(err != OK, "Cannot open directory '" + base_dir + "'."); - - print_verbose("Making folder " + path + " in " + base_dir); - err = da->make_dir_recursive(path); - + Error err = EditorFileSystem::get_singleton()->make_dir_recursive(path, base_dir); if (err == OK) { emit_signal(SNAME("dir_created"), base_dir.path_join(path)); } else { diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index de4e9240f6..24fc7a9c2b 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -657,6 +657,7 @@ Variant EditorAudioBus::get_drag_data_fw(const Point2 &p_point, Control *p_from) Label *l = memnew(Label); l->set_text(item->get_text(0)); + l->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); effects->set_drag_preview(l); return fxd; @@ -929,6 +930,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { hb->add_child(scale); effects = memnew(Tree); + effects->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); effects->set_hide_root(true); effects->set_custom_minimum_size(Size2(0, 80) * EDSCALE); effects->set_hide_folding(true); @@ -954,6 +956,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) { set_focus_mode(FOCUS_CLICK); effect_options = memnew(PopupMenu); + effect_options->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate class names. effect_options->connect("index_pressed", callable_mp(this, &EditorAudioBus::_effect_add)); add_child(effect_options); List<StringName> effect_list; diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index fb007aee28..0eabe53360 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -644,6 +644,7 @@ Variant EditorAutoloadSettings::get_drag_data_fw(const Point2 &p_point, Control for (int i = 0; i < max_size; i++) { Label *label = memnew(Label(autoloads[i])); label->set_self_modulate(Color(1, 1, 1, Math::lerp(1, 0, float(i) / PREVIEW_LIST_MAX_SIZE))); + label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); preview->add_child(label); } diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index cad615e6c5..adae6599c1 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/extension/gdextension_manager.h" +#include "core/io/dir_access.h" #include "core/io/file_access.h" #include "core/io/resource_saver.h" #include "core/object/worker_thread_pool.h" @@ -3075,33 +3076,51 @@ void EditorFileSystem::move_group_file(const String &p_path, const String &p_new } } -void EditorFileSystem::add_new_directory(const String &p_path) { - String path = p_path.get_base_dir(); - EditorFileSystemDirectory *parent = filesystem; - int base = p_path.count("/"); - int max_bit = base + 1; +Error EditorFileSystem::make_dir_recursive(const String &p_path, const String &p_base_path) { + Error err; + Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + if (!p_base_path.is_empty()) { + err = da->change_dir(p_base_path); + ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open base directory '" + p_base_path + "'."); + } - while (path != "res://") { - EditorFileSystemDirectory *dir = get_filesystem_path(path); - if (dir) { - parent = dir; - break; - } - path = path.get_base_dir(); - base--; + if (da->dir_exists(p_path)) { + return ERR_ALREADY_EXISTS; + } + + err = da->make_dir_recursive(p_path); + if (err != OK) { + return err; } - for (int i = base; i < max_bit; i++) { + const String path = da->get_current_dir(); + EditorFileSystemDirectory *parent = get_filesystem_path(path); + ERR_FAIL_NULL_V(parent, ERR_FILE_NOT_FOUND); + + const PackedStringArray folders = p_path.trim_prefix(path).trim_suffix("/").split("/"); + bool first = true; + + for (const String &folder : folders) { + const int current = parent->find_dir_index(folder); + if (current > -1) { + parent = parent->get_subdir(current); + continue; + } + EditorFileSystemDirectory *efd = memnew(EditorFileSystemDirectory); efd->parent = parent; - efd->name = p_path.get_slice("/", i); + efd->name = folder; parent->subdirs.push_back(efd); - if (i == base) { + if (first) { parent->subdirs.sort_custom<DirectoryComparator>(); + first = false; } parent = efd; } + + emit_signal(SNAME("filesystem_changed")); + return OK; } ResourceUID::ID EditorFileSystem::_resource_saver_get_resource_id_for_path(const String &p_path, bool p_generate) { diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index be299800d8..e02127cb13 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -370,7 +370,7 @@ public: bool is_group_file(const String &p_path) const; void move_group_file(const String &p_path, const String &p_new_path); - void add_new_directory(const String &p_path); + Error make_dir_recursive(const String &p_path, const String &p_base_path = String()); static bool _should_skip_directory(const String &p_path); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 4cd0761691..a215662f16 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -893,6 +893,7 @@ Variant EditorProperty::get_drag_data(const Point2 &p_point) { Label *drag_label = memnew(Label); drag_label->set_text(property); + drag_label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate raw property name. set_drag_preview(drag_label); return dp; } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 2c474c3c70..0eb566f9be 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -5665,6 +5665,7 @@ Dictionary EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from Control *drag_control = memnew(Control); TextureRect *drag_preview = memnew(TextureRect); Label *label = memnew(Label); + label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); Ref<Texture2D> preview; @@ -5717,6 +5718,7 @@ Dictionary EditorNode::drag_files_and_dirs(const Vector<String> &p_paths, Contro HBoxContainer *hbox = memnew(HBoxContainer); TextureRect *icon = memnew(TextureRect); Label *label = memnew(Label); + label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); if (p_paths[i].ends_with("/")) { label->set_text(p_paths[i].substr(0, p_paths[i].length() - 1).get_file()); diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index 81bc9c8fbe..b133847823 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -697,7 +697,7 @@ Variant EditorSettingsDialog::get_drag_data_fw(const Point2 &p_point, Control *p return Variant(); } - String label_text = "Event " + itos(selected->get_meta("event_index")); + String label_text = vformat(TTRC("Event %d"), selected->get_meta("event_index")); Label *label = memnew(Label(label_text)); label->set_modulate(Color(1, 1, 1, 1.0f)); shortcuts->set_drag_preview(label); diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp index 3ad8ab0b19..be9e0f78ec 100644 --- a/editor/export/project_export.cpp +++ b/editor/export/project_export.cpp @@ -713,6 +713,7 @@ Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_ drag->add_child(tr); Label *label = memnew(Label); label->set_text(presets->get_item_text(pos)); + label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate user input. drag->add_child(label); presets->set_drag_preview(drag); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 1082e4d0c2..dd2eec6893 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -649,8 +649,7 @@ void FileSystemDock::_notification(int p_what) { } if (do_redraw) { - _update_file_list(true); - _update_tree(get_uncollapsed_paths()); + update_all(); } if (EditorThemeManager::is_generated_theme_outdated()) { @@ -1343,13 +1342,7 @@ void FileSystemDock::_fs_changed() { scanning_vb->hide(); split_box->show(); - if (tree->is_visible()) { - _update_tree(get_uncollapsed_paths()); - } - - if (file_list_vb->is_visible()) { - _update_file_list(true); - } + update_all(); if (!select_after_scan.is_empty()) { _navigate_to_path(select_after_scan); @@ -1361,15 +1354,6 @@ void FileSystemDock::_fs_changed() { set_process(false); } -void FileSystemDock::_directory_created(const String &p_path) { - if (!DirAccess::exists(p_path)) { - return; - } - EditorFileSystem::get_singleton()->add_new_directory(p_path); - _update_tree(get_uncollapsed_paths()); - _update_file_list(true); -} - void FileSystemDock::_set_scanning_mode() { button_hist_prev->set_disabled(true); button_hist_next->set_disabled(true); @@ -2678,8 +2662,11 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; default: { - // Resource conversion commands: - if (p_option >= CONVERT_BASE_ID) { + if (p_option >= EditorContextMenuPlugin::BASE_ID) { + if (!EditorContextMenuPluginManager::get_singleton()->activate_custom_option(EditorContextMenuPlugin::CONTEXT_SLOT_FILESYSTEM, p_option, p_selected)) { + EditorContextMenuPluginManager::get_singleton()->activate_custom_option(EditorContextMenuPlugin::CONTEXT_SLOT_FILESYSTEM_CREATE, p_option, p_selected); + } + } else if (p_option >= CONVERT_BASE_ID) { selected_conversion_id = p_option - CONVERT_BASE_ID; ERR_FAIL_INDEX(selected_conversion_id, (int)cached_valid_conversion_targets.size()); @@ -2697,10 +2684,6 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } conversion_id++; } - } else { - if (!EditorContextMenuPluginManager::get_singleton()->activate_custom_option(EditorContextMenuPlugin::CONTEXT_SLOT_FILESYSTEM, p_option, p_selected)) { - EditorContextMenuPluginManager::get_singleton()->activate_custom_option(EditorContextMenuPlugin::CONTEXT_SLOT_FILESYSTEM_CREATE, p_option, p_selected); - } } break; } @@ -2820,6 +2803,16 @@ void FileSystemDock::fix_dependencies(const String &p_for_file) { deps_editor->edit(p_for_file); } +void FileSystemDock::update_all() { + if (tree->is_visible()) { + _update_tree(get_uncollapsed_paths()); + } + + if (file_list_vb->is_visible()) { + _update_file_list(true); + } +} + void FileSystemDock::focus_on_path() { current_path_line_edit->grab_focus(); current_path_line_edit->select_all(); @@ -3241,9 +3234,7 @@ void FileSystemDock::_folder_color_index_pressed(int p_index, PopupMenu *p_menu) } _update_folder_colors_setting(); - - _update_tree(get_uncollapsed_paths()); - _update_file_list(true); + update_all(); emit_signal(SNAME("folder_color_changed")); } @@ -3951,8 +3942,7 @@ void FileSystemDock::set_file_sort(FileSortOption p_file_sort) { file_sort = p_file_sort; // Update everything needed. - _update_tree(get_uncollapsed_paths()); - _update_file_list(true); + update_all(); } void FileSystemDock::_file_sort_popup(int p_id) { @@ -4342,7 +4332,6 @@ FileSystemDock::FileSystemDock() { make_dir_dialog = memnew(DirectoryCreateDialog); add_child(make_dir_dialog); - make_dir_dialog->connect("dir_created", callable_mp(this, &FileSystemDock::_directory_created)); make_scene_dialog = memnew(SceneCreateDialog); add_child(make_scene_dialog); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 751fbed022..108b646029 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -270,7 +270,6 @@ private: void _toggle_file_display(); void _set_file_display(bool p_active); void _fs_changed(); - void _directory_created(const String &p_path); void _select_file(const String &p_path, bool p_select_in_favorites = false); void _tree_activate_file(); @@ -417,6 +416,7 @@ public: ScriptCreateDialog *get_script_create_dialog() const; void fix_dependencies(const String &p_for_file); + void update_all(); int get_h_split_offset() const { return split_box_offset_h; } void set_h_split_offset(int p_offset) { split_box_offset_h = p_offset; } diff --git a/editor/gui/editor_dir_dialog.cpp b/editor/gui/editor_dir_dialog.cpp index e64761d5b5..b677ba1098 100644 --- a/editor/gui/editor_dir_dialog.cpp +++ b/editor/gui/editor_dir_dialog.cpp @@ -191,7 +191,6 @@ void EditorDirDialog::_make_dir_confirm(const String &p_path) { } new_dir_path = p_path + "/"; - EditorFileSystem::get_singleton()->scan_changes(); // We created a dir, so rescan changes. } void EditorDirDialog::_bind_methods() { diff --git a/editor/gui/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp index 6695abb70a..2e36b66025 100644 --- a/editor/gui/scene_tree_editor.cpp +++ b/editor/gui/scene_tree_editor.cpp @@ -1361,6 +1361,7 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from tf->set_texture(icons[i]); hb->add_child(tf); Label *label = memnew(Label(selected_nodes[i]->get_name())); + label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); hb->add_child(label); vb->add_child(hb); hb->set_modulate(Color(1, 1, 1, opacity_item)); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index ba9fd4e66c..dc86acd884 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -3997,7 +3997,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { xform.orthonormalize(); xform.basis.scale(scale); RenderingServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[3], xform); - RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], spatial_editor->is_gizmo_visible() && transform_gizmo_visible && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE)); + RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], spatial_editor->is_gizmo_visible() && !_edit.instant && transform_gizmo_visible && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE)); } void Node3DEditorViewport::set_state(const Dictionary &p_state) { diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index af401ee6a3..9579388d46 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -3101,6 +3101,7 @@ Variant ScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { drag_preview->add_child(tf); } Label *label = memnew(Label(preview_name)); + label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate script names and class names. drag_preview->add_child(label); set_drag_preview(drag_preview); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 6bfe78c216..6b00a2c9c5 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -614,6 +614,7 @@ Variant ShaderEditorPlugin::get_drag_data_fw(const Point2 &p_point, Control *p_f drag_preview->add_child(tf); } Label *label = memnew(Label(preview_name)); + label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Don't translate script names. drag_preview->add_child(label); main_split->set_drag_preview(drag_preview); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 64b9522864..81beaf6f91 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -689,6 +689,7 @@ Variant Skeleton3DEditor::get_drag_data_fw(const Point2 &p_point, Control *p_fro tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); hb->add_child(tf); Label *label = memnew(Label(selected->get_text(0))); + label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); hb->add_child(label); vb->add_child(hb); hb->set_modulate(Color(1, 1, 1, 1)); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 412d58cf45..c378bf315b 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -5994,6 +5994,7 @@ Variant VisualShaderEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f Label *label = memnew(Label); label->set_text(it->get_text(0)); + label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); set_drag_preview(label); return d; } @@ -6560,6 +6561,7 @@ VisualShaderEditor::VisualShaderEditor() { parameters->set_hide_folding(false); parameters->set_h_size_flags(SIZE_EXPAND_FILL); parameters->set_v_size_flags(SIZE_EXPAND_FILL); + parameters->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); parameters->connect(SceneStringName(item_selected), callable_mp(this, &VisualShaderEditor::_param_selected)); parameters->connect("nothing_selected", callable_mp(this, &VisualShaderEditor::_param_unselected)); sc->add_child(parameters); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 95952f9b87..d00fdc2123 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -267,7 +267,7 @@ void ProjectSettingsEditor::shortcut_input(const Ref<InputEvent> &p_event) { String ProjectSettingsEditor::_get_setting_name() const { String name = property_box->get_text().strip_edges(); - if (!name.contains("/")) { + if (!name.begins_with("_") && !name.contains("/")) { name = "global/" + name; } return name; |