From 77d10601c77b35d5480f4e73a9b0f74c21729437 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 5 May 2022 10:36:26 -0700 Subject: [PATCH 1/7] SL-16916: Fix incorrect defaults for minimap rotation and minimap scale --- indra/newview/app_settings/settings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 05d04e38db..74241823f4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6797,7 +6797,7 @@ Type Boolean Value - 1 + 0 MiniMapScale @@ -6808,7 +6808,7 @@ Type F32 Value - 64.0 + 128.0 MiniMapShowPropertyLines From 7565e734d29112e14e885a6097805c1315b81917 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 10 May 2022 14:57:24 -0700 Subject: [PATCH 2/7] SL-2243 - match server physics shape calculation re mesh dimensions --- indra/newview/llphysicsshapebuilderutil.cpp | 13 ++++++++++++- indra/newview/llphysicsshapebuilderutil.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp index 5bfe5c9941..9603ee6329 100644 --- a/indra/newview/llphysicsshapebuilderutil.cpp +++ b/indra/newview/llphysicsshapebuilderutil.cpp @@ -29,7 +29,7 @@ #include "llphysicsshapebuilderutil.h" /* static */ -void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut ) +void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut) { const LLProfileParams& profile_params = volume_params.getProfileParams(); const LLPathParams& path_params = volume_params.getPathParams(); @@ -191,6 +191,7 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara if ( volume_params.shouldForceConvex() ) { + // Server distinguishes between convex of a prim vs isSculpt, but we don't care. specOut.mType = PhysicsShapeSpecification::USER_CONVEX; } // Make a simpler convex shape if we can. @@ -199,6 +200,16 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara { specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; } + else if (volume_params.isMeshSculpt() && + // Check overall dimensions, not individual triangles. + (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE + ) ) + { + // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't. + specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; + } else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy) { specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT; diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h index bd5b7d799c..b3b100296f 100644 --- a/indra/newview/llphysicsshapebuilderutil.h +++ b/indra/newview/llphysicsshapebuilderutil.h @@ -47,6 +47,7 @@ const F32 SHAPE_BUILDER_ENTRY_SNAP_SCALE_BIN_SIZE = 0.15f; const F32 SHAPE_BUILDER_ENTRY_SNAP_PARAMETER_BIN_SIZE = 0.010f; const F32 SHAPE_BUILDER_CONVEXIFICATION_SIZE = 2.f * COLLISION_TOLERANCE; const F32 SHAPE_BUILDER_MIN_GEOMETRY_SIZE = 0.5f * COLLISION_TOLERANCE; +const F32 SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE = 0.5f; class LLPhysicsVolumeParams : public LLVolumeParams { From f7edcab9c3187a2dc797db614ba0302ed7eed578 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 7 Dec 2018 21:27:12 +0000 Subject: [PATCH 3/7] SL-288, SL-10163 - allow joint aliases, but otherwise reject upload of animations containing invalid joint names # Conflicts: # indra/newview/llviewerassetupload.cpp # indra/newview/llvoavatar.cpp --- indra/llappearance/llavatarappearance.cpp | 4 +- indra/llcharacter/llkeyframemotion.cpp | 10 ++++- indra/llcharacter/llkeyframemotion.h | 2 +- indra/newview/llfloaterbvhpreview.cpp | 2 +- indra/newview/llviewerassetupload.cpp | 49 ++++++++++++++++++++++- indra/newview/llvoavatar.cpp | 13 +++++- 6 files changed, 71 insertions(+), 9 deletions(-) diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 90dfa04f28..6c77a9242e 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -927,6 +927,9 @@ BOOL LLAvatarAppearance::loadAvatar() return FALSE; } + // initialize mJointAliasMap + getJointAliases(); + // avatar_lad.xml : if( !loadSkeletonNode() ) { @@ -1047,7 +1050,6 @@ BOOL LLAvatarAppearance::loadAvatar() return FALSE; } } - return TRUE; } diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index f2584ee6f3..daff69c73a 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1221,8 +1221,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 //----------------------------------------------------------------------------- // deserialize() +// +// allow_invalid_joints should be true when handling existing content, to avoid breakage. +// During upload, we should be more restrictive and reject such animations. //----------------------------------------------------------------------------- -BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) +BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints) { BOOL old_version = FALSE; mJointMotionList = new LLKeyframeMotion::JointMotionList; @@ -1464,7 +1467,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) { LL_WARNS() << "invalid joint name: " << joint_name << " for animation " << asset_id << LL_ENDL; - //return FALSE; + if (!allow_invalid_joints) + { + return FALSE; + } } joint_motion->mJointName = joint_name; diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index 9a927ede9a..ff29a90010 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -156,7 +156,7 @@ public: public: U32 getFileSize(); BOOL serialize(LLDataPacker& dp) const; - BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id); + BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true); BOOL isLoaded() { return mJointMotionList != NULL; } void dumpToFile(const std::string& name); diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 687d820a18..09cf44bdf2 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -294,7 +294,7 @@ BOOL LLFloaterBvhPreview::postBuild() loaderp->serialize(dp); dp.reset(); LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL; - BOOL success = motionp && motionp->deserialize(dp, mMotionID); + BOOL success = motionp && motionp->deserialize(dp, mMotionID, false); LL_INFOS("BVH") << "Done" << LL_ENDL; delete []buffer; diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 3f7e8531fb..a320f07a9f 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -450,9 +450,54 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile() errorLabel = "DoNotSupportBulkAnimationUpload"; error = true; } - else if (assetType == LLAssetType::AT_ANIMATION) + else if (exten == "anim") { - filename = getFileName(); + // Default unless everything succeeds + errorLabel = "ProblemWithFile"; + error = true; + + // read from getFileName() + LLAPRFile infile; + infile.open(getFileName(),LL_APR_RB); + if (!infile.getFileHandle()) + { + LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL; + errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str()); + } + else + { + S32 size = LLAPRFile::size(getFileName()); + U8* buffer = new U8[size]; + S32 size_read = infile.read(buffer,size); + if (size_read != size) + { + errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read); + } + else + { + LLDataPackerBinaryBuffer dp(buffer, size); + LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId()); + motionp->setCharacter(gAgentAvatarp); + if (motionp->deserialize(dp, getAssetId(), false)) + { + // write to temp file + bool succ = motionp->dumpToFile(filename); + if (succ) + { + assetType = LLAssetType::AT_ANIMATION; + errorLabel = ""; + error = false; + } + } + } + } + } + else + { + // Unknown extension + errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str()); + errorLabel = "ErrorMessage"; + error = TRUE;; } if (error) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d421b3b1f6..487730e209 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6145,8 +6145,17 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) LLJoint* jointp = NULL; if (iter == mJointMap.end() || iter->second == NULL) - { //search for joint and cache found joint in lookup table - jointp = mRoot->findJoint(name); + joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name); + std::string canonical_name; + if (alias_iter != mJointAliasMap.end()) + { + canonical_name = alias_iter->second; + } + else + { + canonical_name = name; + } + jointp = mRoot->findJoint(canonical_name); mJointMap[name] = jointp; } else From 4413f9be879c14328988ce4d285c1dfa263db027 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 10 Dec 2018 15:02:41 +0000 Subject: [PATCH 4/7] SL-288, SL-10163 - error reporting for animation upload failures. --- indra/newview/llviewerassetupload.cpp | 9 +++++++++ indra/newview/llvoavatar.cpp | 1 + 2 files changed, 10 insertions(+) diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index a320f07a9f..7c6721cad9 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -488,6 +488,14 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile() errorLabel = ""; error = false; } + else + { + errorMessage = "Failed saving temporary animation file"; + } + } + else + { + errorMessage = "Failed reading animation file"; } } } @@ -908,6 +916,7 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res { args["FILE"] = uploadInfo->getDisplayName(); args["REASON"] = reason; + args["ERROR"] = reason; } LLNotificationsUtil::add(label, args); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 487730e209..b1f04601fd 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6145,6 +6145,7 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) LLJoint* jointp = NULL; if (iter == mJointMap.end() || iter->second == NULL) + { joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name); std::string canonical_name; if (alias_iter != mJointAliasMap.end()) From 307db06310d6d3dc5a38da5543d0f074266fb12a Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 6 Dec 2018 21:58:14 +0000 Subject: [PATCH 5/7] SL-10163 - allow joint aliases in animation uploads. Names are canonicalized before sending to simulator. # Conflicts: # indra/newview/llviewerassetupload.cpp # indra/newview/llvoavatar.cpp # scripts/content_tools/anim_tool.py --- indra/llcharacter/llkeyframemotion.cpp | 26 ++++++++++++++++++++++---- indra/llcharacter/llkeyframemotion.h | 5 ++++- indra/newview/llviewerassetupload.cpp | 4 ++++ indra/newview/llvoavatar.cpp | 6 +++++- scripts/content_tools/anim_tool.py | 8 +++++++- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index daff69c73a..1eee736b48 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1453,6 +1453,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo if (joint) { S32 joint_num = joint->getJointNum(); + joint_name = joint->getName(); // canonical name in case this is an alias. // LL_INFOS() << " joint: " << joint_name << LL_ENDL; if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0)) { @@ -2109,8 +2110,9 @@ U32 LLKeyframeMotion::getFileSize() //----------------------------------------------------------------------------- // dumpToFile() //----------------------------------------------------------------------------- -void LLKeyframeMotion::dumpToFile(const std::string& name) +bool LLKeyframeMotion::dumpToFile(const std::string& name) { + bool succ = false; if (isLoaded()) { std::string outfile_base; @@ -2127,10 +2129,24 @@ void LLKeyframeMotion::dumpToFile(const std::string& name) const LLUUID& id = getID(); outfile_base = id.asString(); } - std::string outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base + ".anim"); + + if (gDirUtilp->getExtension(outfile_base).empty()) + { + outfile_base += ".anim"; + } + std::string outfilename; + if (gDirUtilp->getDirName(outfile_base).empty()) + { + outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base); + } + else + { + outfilename = outfile_base; + } if (LLFile::isfile(outfilename)) { - return; + LL_WARNS() << outfilename << " already exists, write failed" << LL_ENDL; + return false; } S32 file_size = getFileSize(); @@ -2144,11 +2160,13 @@ void LLKeyframeMotion::dumpToFile(const std::string& name) outfile.open(outfilename, LL_APR_WPB); if (outfile.getFileHandle()) { - outfile.write(buffer, file_size); + S32 wrote_bytes = outfile.write(buffer, file_size); + succ = (wrote_bytes == file_size); } } delete [] buffer; } + return succ; } //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index ff29a90010..96746f57c9 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -158,7 +158,7 @@ public: BOOL serialize(LLDataPacker& dp) const; BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true); BOOL isLoaded() { return mJointMotionList != NULL; } - void dumpToFile(const std::string& name); + bool dumpToFile(const std::string& name); // setters for modifying a keyframe animation @@ -432,6 +432,9 @@ protected: F32 mLastUpdateTime; F32 mLastLoopedTime; AssetStatus mAssetStatus; + +public: + void setCharacter(LLCharacter* character) { mCharacter = character; } }; class LLKeyframeDataCache diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 7c6721cad9..14fae8d035 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -50,6 +50,10 @@ #include "llpreviewnotecard.h" #include "llpreviewgesture.h" #include "llcoproceduremanager.h" +#include "llthread.h" +#include "llkeyframemotion.h" +#include "lldatapacker.h" +#include "llvoavatarself.h" void dialog_refresh_all(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index b1f04601fd..8c8025e352 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6145,7 +6145,11 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) LLJoint* jointp = NULL; if (iter == mJointMap.end() || iter->second == NULL) - { + { //search for joint and cache found joint in lookup table + if (mJointAliasMap.empty()) + { + getJointAliases(); + } joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name); std::string canonical_name; if (alias_iter != mJointAliasMap.end()) diff --git a/scripts/content_tools/anim_tool.py b/scripts/content_tools/anim_tool.py index e7b86a88fa..205fc2b6e1 100644 --- a/scripts/content_tools/anim_tool.py +++ b/scripts/content_tools/anim_tool.py @@ -637,6 +637,7 @@ def main(*argv): parser.add_argument("--no_hud", help="omit hud joints from list of attachments", action="store_true") parser.add_argument("--base_priority", help="set base priority", type=int) parser.add_argument("--joint_priority", help="set joint priority for all joints", type=int) + parser.add_argument("--force_joints", help="don't check validity of joint names", action="store_true") parser.add_argument("infilename", help="name of a .anim file to input") parser.add_argument("outfilename", nargs="?", help="name of a .anim file to output") args = parser.parse_args(argv) @@ -661,7 +662,12 @@ def main(*argv): if lad_tree is None: raise Error("failed to parse " + args.lad) if args.joints: - joints = resolve_joints(args.joints, skel_tree, lad_tree, args.no_hud) + if args.force_joints: + joints = args.joints + else: + joints = resolve_joints(args.joints, skel_tree, lad_tree, args.no_hud) + if args.use_aliases: + joints = map(lambda name: "avatar_" + name, joints) if args.verbose: print("joints resolved to",joints) for name in joints: From b3bfe05494aa12d87728f7df93ce72bc25019b33 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 4 Dec 2018 20:02:25 +0000 Subject: [PATCH 6/7] SL-10025 - via Cathy Foil, all bones now have standard alias 'avatar_' + name. # Conflicts: # scripts/content_tools/anim_tool.py --- indra/newview/character/avatar_skeleton.xml | 214 ++++++++++---------- scripts/content_tools/anim_tool.py | 1 + scripts/content_tools/skel_tool.py | 17 ++ 3 files changed, 125 insertions(+), 107 deletions(-) diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml index 2241a12545..6cfc0b0be2 100644 --- a/indra/newview/character/avatar_skeleton.xml +++ b/indra/newview/character/avatar_skeleton.xml @@ -2,15 +2,15 @@ - - + + - - + + @@ -23,58 +23,58 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - + + + @@ -86,29 +86,29 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + @@ -123,49 +123,49 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - - - + + + + + + - - - - - + + + + + @@ -200,30 +200,30 @@ - - - - - - + + + + + + - - - - - - + + + + + + - - - - + + + + diff --git a/scripts/content_tools/anim_tool.py b/scripts/content_tools/anim_tool.py index 205fc2b6e1..4a0773951e 100644 --- a/scripts/content_tools/anim_tool.py +++ b/scripts/content_tools/anim_tool.py @@ -611,6 +611,7 @@ def main(*argv): parser = argparse.ArgumentParser(description="process SL animations") parser.add_argument("--verbose", help="verbose flag", action="store_true") parser.add_argument("--dump", help="dump to stdout", action="store_true") + parser.add_argument("--use_aliases", help="use alias names for bones", action="store_true") parser.add_argument("--rot", help="specify sequence of rotations", type=float_triple, nargs="+") parser.add_argument("--rand_pos", help="request NUM random positions (default %(default)s)", metavar="NUM", type=int, default=2) diff --git a/scripts/content_tools/skel_tool.py b/scripts/content_tools/skel_tool.py index 449ecd6a6c..696e4e2923 100644 --- a/scripts/content_tools/skel_tool.py +++ b/scripts/content_tools/skel_tool.py @@ -72,6 +72,22 @@ def check_symmetry(name, field, vec1, vec2): if vec1[2] != vec2[2]: print(name,field,"z match fail") +def enforce_alias_rules(tree, element, fix=False): + if element.tag != "bone": + return + alias_lis = [] + aliases = element.get("aliases") + if aliases: + alias_lis = aliases.split(" ") + name = element.get("name") + if name: + std_alias = "avatar_" + name + if not std_alias in alias_lis: + print "missing expected alias",name,std_alias + for alias in alias_lis: + if alias.startswith("avatar_") and alias != std_alias: + print "invalid avatar_ alias",name,alias + def enforce_symmetry(tree, element, field, fix=False): name = element.get("name") if not name: @@ -209,6 +225,7 @@ def validate_skel_tree(tree, ogtree, reftree, fix=False): unfixable += 1 fix_name(element) + enforce_alias_rules(tree, element, fix) enforce_precision_rules(element) for field in ["pos","pivot"]: enforce_symmetry(tree, element, field, fix) From eaf9171aca0f1073674a009548fc86eb2d623c4b Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 19 May 2022 11:18:05 +0300 Subject: [PATCH 7/7] SL-17404 Adjust 'More' button width --- indra/newview/skins/default/xui/ru/panel_navigation_bar.xml | 2 +- indra/newview/skins/default/xui/tr/panel_navigation_bar.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml index 5e3de180f9..331ba889d8 100644 --- a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml @@ -14,7 +14,7 @@ - + Больше ▼ diff --git a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml index 8d43e3fb5a..ae9bc33bfa 100644 --- a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml @@ -14,7 +14,7 @@ - + Daha Fazla ▼