Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stringtables #84

Merged
merged 36 commits into from
Mar 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
748a95c
Add First Stringtable work
jokoho48 Mar 16, 2020
f502be7
move more strings to stringtable
jokoho48 Mar 16, 2020
e647997
Merge branch 'master' into Stringtables
jokoho48 Mar 17, 2020
0ab377f
Merge branch 'master' into Stringtables
jokoho48 Mar 18, 2020
d235e7e
add Localization support to showDialog
jokoho48 Mar 18, 2020
4ee2021
move some more stuff to stringtables
jokoho48 Mar 19, 2020
8216332
move some more stuff to stringtables
jokoho48 Mar 19, 2020
4b0ca10
fix a regex issue
jokoho48 Mar 19, 2020
91b5c29
Merge branch 'master' into Stringtables
jokoho48 Mar 20, 2020
a555e3c
Merge branch 'master' into Stringtables
jokoho48 Mar 22, 2020
ccd46e5
add some more L10n
jokoho48 Mar 22, 2020
9e895b6
add some more L10n
jokoho48 Mar 22, 2020
c6a31c7
add some more L10n
jokoho48 Mar 22, 2020
0d789d9
add stringtable_validator
jokoho48 Mar 22, 2020
e3f3786
add StringtableValidator to github Actions
jokoho48 Mar 22, 2020
c9f79be
update step name
jokoho48 Mar 22, 2020
897591d
add translation issue autoupdate
jokoho48 Mar 22, 2020
3d39e26
update
jokoho48 Mar 22, 2020
afbcee4
move stringtables to main workflow
jokoho48 Mar 22, 2020
0627a89
STRINGTABLES
jokoho48 Mar 24, 2020
584e826
STRINGTABLES
jokoho48 Mar 24, 2020
111bdaa
STRINGTABLES
jokoho48 Mar 24, 2020
ffb8d29
STRINGTABLES
jokoho48 Mar 24, 2020
f738040
STRINGTABLES
jokoho48 Mar 24, 2020
8fa87a9
STRINGTABLES
jokoho48 Mar 24, 2020
819ee3e
STRINGTABLES
jokoho48 Mar 24, 2020
2b4aa20
STRINGTABLES
jokoho48 Mar 24, 2020
3bec511
STRINGTABLES
jokoho48 Mar 24, 2020
1f5a697
STRINGTABLES
jokoho48 Mar 24, 2020
d65eec9
linter fix
jokoho48 Mar 24, 2020
b58d48d
STRINGTABLES
jokoho48 Mar 25, 2020
e409294
STRINGTABLES
jokoho48 Mar 25, 2020
9f99082
add CfgSettings for CBA min Version Requirment
jokoho48 Mar 23, 2020
d838735
- Fixed missing module descriptions (damned brs!)
nk3nny Mar 26, 2020
b7a1d8b
add 2 missed Strings
jokoho48 Mar 26, 2020
97bcddb
update Arma Workflow
jokoho48 Mar 26, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: CI
name: Arma

on: [push]
on: [push, pull_request]

jobs:
validate:
Expand Down Expand Up @@ -43,3 +43,22 @@ jobs:
with:
name: '@LambsDanger'
path: 'releases/@LambsDanger.zip'

stringtables:
runs-on: ubuntu-latest
steps:
- name: Install Python packages
run: |
pip3 install wheel
pip3 install setuptools
pip3 install pygithub
pip3 install pygithub3
- name: Checkout the source code
uses: actions/checkout@master
- name: Validate Stringtables
run: python3 tools/stringtable_validator.py
- name: Update Translation issue
if: github.repository == 'nk3nny/LambsDanger' && github.branch == 'master' && ! contains(github.event.head_commit.message, '[ci skip]')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: python3 tools/stringtableDeploy.py
8 changes: 4 additions & 4 deletions addons/danger/Cfg3DEN.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ class Cfg3DEN {
class GVAR(disableAI) {
property = QGVAR(disableAI);
control = "Checkbox";
displayName = "AI Disabled";
tooltip = "Unit has advanced danger.fsm features disabled\n\nWARNING checking this will add mod dependency";
displayName = CSTRING(3DEN_Attributes_DisableAI_DisplayName);
tooltip = CSTRING(3DEN_Attributes_DisableAI_ToolTip);
expression = "if (_value) then { _this setVariable ['%s', _value, true]; }";
typeName = "BOOL";
condition = "objectBrain";
Expand All @@ -18,8 +18,8 @@ class Cfg3DEN {
class GVAR(dangerRadio) {
property = QGVAR(dangerRadio);
control = "Checkbox";
displayName = "Has Radio";
tooltip = "Unit counts as carrying backpack radio for information sharing\n\nWARNING checking this will add mod dependency";
displayName = CSTRING(3DEN_Attributes_HasRadio_DisplayName);
tooltip = CSTRING(3DEN_Attributes_HasRadio_ToolTip);
expression = "if (_value) then { _this setVariable ['%s', _value, true]; }";
typeName = "BOOL";
condition = "objectBrain";
Expand Down
6 changes: 3 additions & 3 deletions addons/danger/CfgVehicles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ class CfgVehicles {
_generalMacro = QGVAR(SetRadio);
scope = 1;
scopeCurator = 2;
displayName = CSTRING(Module_SetRadio_DisplayName);
isGlobal = 0;
displayName = "Configure Long-range Radio";
category = "Lambs_Danger_Cat";
icon = "\A3\ui_f\data\igui\cfg\simpleTasks\types\intel_ca.paa";
function = QFUNC(moduleSetRadio);
Expand All @@ -39,8 +39,8 @@ class CfgVehicles {
_generalMacro = QGVAR(DisableAI);
scope = 1;
scopeCurator = 2;
displayName = CSTRING(Module_DisableAI_DisplayName);
isGlobal = 0;
displayName = "Disable Unit AI";
category = "Lambs_Danger_Cat";
icon = "\A3\ui_f\data\igui\cfg\simpleTasks\types\intel_ca.paa";
function = QFUNC(moduleDisableAI);
Expand All @@ -56,8 +56,8 @@ class CfgVehicles {
_generalMacro = QGVAR(DisableGroupAI);
scope = 1;
scopeCurator = 2;
displayName = CSTRING(Module_DisableGroupAI_DisplayName);
isGlobal = 0;
displayName = "Configure Group AI";
category = "Lambs_Danger_Cat";
icon = "\A3\ui_f\data\igui\cfg\simpleTasks\types\intel_ca.paa";
function = QFUNC(moduleDisableGroupAI);
Expand Down
2 changes: 1 addition & 1 deletion addons/danger/XEH_preInitClient.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private _fnc_suppress_AI = {

// functions ~ easy hide
private _fnc_hide_AI = {
private _buildings = [player getpos [15, getdir player], 38, true, true] call FUNC(findBuildings);
private _buildings = [player getPos [15, getdir player], 38, true, true] call FUNC(findBuildings);
private _units = (units player) select {_x distance player < 55 && {!isPlayer _x}};
{
[_x, _x getPos [25, random 360], 10, _buildings] call FUNC(hideInside);
Expand Down
2 changes: 1 addition & 1 deletion addons/danger/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class CfgPatches {
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"lambs_main"};
author = "LAMBS Dev Team";
author = ECSTRING(main,Team);
VERSION_CONFIG;
};
};
Expand Down
10 changes: 5 additions & 5 deletions addons/danger/functions/ZeusModules/fnc_moduleDisableAI.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ if (_activated && local _logic) then {
//--- Check if the unit is suitable
private _error = "";
if (isNull _unit) then {
_error = "No Unit Selected";
_error = ELSTRING(main,NoUnitSelected);
};
if (isPlayer _unit) then {
_error = "Players are not Valid Selections";
_error = ELSTRING(main,PlayerNotValid);
};
if (_error == "") then {
["Disable Unit AI",
[LSTRING(Module_DisableAI_DisplayName),
[
["Disable LAMBS unit AI", "BOOLEAN", "Toggle advanced danger.fsm features on this unit", _unit getVariable [QGVAR(disableAI), false]]
[LSTRING(Module_DisableAI_SettingName), "BOOLEAN", LSTRING(Module_DisableAI_SettingToolTip), _unit getVariable [QGVAR(disableAI), false]]
], {
params ["_data", "_args"];
_args params ["_unit", "_logic"];
Expand All @@ -34,7 +34,7 @@ if (_activated && local _logic) then {
}, [_unit, _logic]
] call EFUNC(main,showDialog);
} else {
[objNull, _error] call BIS_fnc_showCuratorFeedbackMessage;
[objNull, localize _error] call BIS_fnc_showCuratorFeedbackMessage;
deleteVehicle _logic;
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ if (_activated && local _logic) then {
//--- Check if the unit is suitable
private _error = "";
if (isNull _group) then {
_error = "No Group Selected";
_error = ELSTRING(main,NoGroupSelected);
};

if (_error == "") then {
["Configure Group AI",
[LSTRING(Module_DisableGroupAI_DisplayName),
[
["Disable LAMBS group AI", "BOOLEAN", "Disables LAMBS group AI\nDisabling this feature prevents autonomous building assaults and clearing, as well as hiding from aircraft and tanks", _group getVariable [QGVAR(disableGroupAI), false], ""]
[LSTRING(Module_DisableGroupAI_SettingName), "BOOLEAN", LSTRING(Module_DisableGroupAI_SettingToolTip), _group getVariable [QGVAR(disableGroupAI), false], ""]
], {
params ["_data", "_args"];
_args params ["_group", "_logic"];
Expand All @@ -32,7 +32,7 @@ if (_activated && local _logic) then {
}, [_group, _logic]
] call EFUNC(main,showDialog);
} else {
[objNull, _error] call BIS_fnc_showCuratorFeedbackMessage;
[objNull, localize _error] call BIS_fnc_showCuratorFeedbackMessage;
deleteVehicle _logic;
};
};
10 changes: 5 additions & 5 deletions addons/danger/functions/ZeusModules/fnc_moduleSetRadio.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ if (_activated && local _logic) then {
//--- Check if the unit is suitable
private _error = "";
if (isNull _unit) then {
_error = "No Unit Seleted";
_error = ELSTRING(main,NoUnitSelected);
};
if (isPlayer _unit) then {
_error = "Players are not Valid Selections";
_error = ELSTRING(main,PlayerNotValid);
};
if (_error == "") then {
["Configure Long-range Radio",
[LSTRING(Module_SetRadio_DisplayName),
[
["Toggle boosted communication range on unit", "BOOLEAN", "Unit with radio toggled have boosted communications range when sharing information\nThis effect is also achieved by equipping the unit with a Vanilla Radio Backpack or TFAR-mod enabled radio.", _unit getVariable [QGVAR(dangerRadio), false]]
[LSTRING(Module_SetRadio_SettingName), "BOOLEAN", LSTRING(Module_SetRadio_SettingToolTip), _unit getVariable [QGVAR(dangerRadio), false]]
], {
params ["_data", "_args"];
_args params ["_unit", "_logic"];
Expand All @@ -34,7 +34,7 @@ if (_activated && local _logic) then {
}, [_unit, _logic]
] call EFUNC(main,showDialog);
} else {
[objNull, _error] call BIS_fnc_showCuratorFeedbackMessage;
[objNull, localize _error] call BIS_fnc_showCuratorFeedbackMessage;
deleteVehicle _logic;
};
};
4 changes: 2 additions & 2 deletions addons/danger/functions/fnc_assault.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ if (RND(0.8) || { count _buildings < 2 }) exitWith {
format ["%1 assaulting position (%2 @ %3m)", side _unit, name _unit, round (_unit distance _target)] call FUNC(debugLog);
private _sphere = createSimpleObject ["Sign_Sphere25cm_F", AGLtoASL (_unit getHideFrom _target), true];
_sphere setObjectTexture [0, [_unit] call FUNC(debugObjectColor)];
[{deleteVehicle _this}, _sphere, 10] call cba_fnc_waitAndExecute;
[{deleteVehicle _this}, _sphere, 10] call CBA_fnc_waitAndExecute;
};
};
};
Expand All @@ -71,7 +71,7 @@ if (GVAR(debug_functions)) then {
_sphere setObjectTexture [0, [_unit] call FUNC(debugObjectColor)];
_sphereList pushBack _sphere;
} foreach _buildings;
[{{deleteVehicle _x;true} count _this}, _sphereList, 15] call cba_fnc_waitAndExecute;
[{{deleteVehicle _x;true} count _this}, _sphereList, 15] call CBA_fnc_waitAndExecute;
};

// end
Expand Down
8 changes: 4 additions & 4 deletions addons/danger/functions/fnc_assaultBuilding.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ if ((_unit distance _enemy) < 7) exitWith {
// movement
_unit doWatch objNull;
_unit lookAt _enemy;
_unit doMove getposATL _enemy;
_unit doMove getPosATL _enemy;
_unit forceSpeed ([_unit, _enemy] call FUNC(assaultSpeed));

// debug
if (GVAR(debug_functions)) then {
format ["%1 assault enemy (%2 @ %3m)", side _unit, name _unit, round (_unit distance _enemy)] call FUNC(debugLog);
private _arrow = createSimpleObject ["Sign_Arrow_Large_F", getposASL _enemy, true];
[{deleteVehicle _this}, _arrow, 20] call cba_fnc_waitAndExecute;
private _arrow = createSimpleObject ["Sign_Arrow_Large_F", getPosASL _enemy, true];
[{deleteVehicle _this}, _arrow, 20] call CBA_fnc_waitAndExecute;
};

// return
Expand Down Expand Up @@ -83,7 +83,7 @@ _unit doMove (_buildingPosSelected vectorAdd [0.5 - random 1, 0.5 - random 1, 0]
if (GVAR(debug_functions)) then {
private _arrow = createSimpleObject ["Sign_Arrow_Large_F", AGLtoASL _buildingPosSelected, true];
_arrow setObjectTexture [0, [_unit] call EFUNC(danger,debugObjectColor)];
[{deleteVehicle _this}, _arrow, 20] call cba_fnc_waitAndExecute;
[{deleteVehicle _this}, _arrow, 20] call CBA_fnc_waitAndExecute;
};

// speed
Expand Down
4 changes: 2 additions & 2 deletions addons/danger/functions/fnc_checkBody.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* boolean
*
* Example:
* [bob, getpos angryJoe, 10] call lambs_danger_fnc_checkBody;
* [bob, getPos angryJoe, 10] call lambs_danger_fnc_checkBody;
*
* Public: No
*/
Expand Down Expand Up @@ -85,7 +85,7 @@ if (GVAR(debug_functions)) then {
// debug arrow
private _help = createSimpleObject ["Sign_Arrow_Large_Yellow_F" ,getPosASL _body, true ];
_help setObjectTexture [0, [_unit] call FUNC(debugObjectColor)];
[{deleteVehicle _this}, _help, 8] call cba_fnc_waitAndExecute;
[{deleteVehicle _this}, _help, 8] call CBA_fnc_waitAndExecute;
};

// end
Expand Down
2 changes: 1 addition & 1 deletion addons/danger/functions/fnc_fleeing.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ if (_unit distance2d _enemy < 120) then {
private _pos = (_unit getPos [(_distance * 0.33) + random (_distance * 0.66), (_enemy getDir _unit) - 35 + random 70]);

// check for water
if (surfaceIsWater _pos) then {_pos = getposASL _unit};
if (surfaceIsWater _pos) then {_pos = getPosASL _unit};

// concealment + pick bushes and rocks if possible
private _objs = nearestTerrainObjects [_pos, ["BUSH", "TREE", "SMALL TREE", "HIDE", "WALL", "FENCE"], 15, false, true];
Expand Down
2 changes: 1 addition & 1 deletion addons/danger/functions/fnc_hideInside.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ if (!(_buildings isEqualTo []) && { RND(0.05) }) then {
private _targetPos = [getPosASL (selectRandom _cover), _unit getPos [45 + random _range, (_danger getDir _unit) + 45 - random 90]] select (_cover isEqualTo []);

// water means hold
if (surfaceIsWater _targetPos) then { _targetPos = getposASL _unit;};
if (surfaceIsWater _targetPos) then { _targetPos = getPosASL _unit;};

// execute move
_unit doMove _targetPos;
Expand Down
2 changes: 1 addition & 1 deletion addons/danger/functions/fnc_leaderArtillery.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
params ["_unit", "_target", ["_pos", []]];

if (_pos isEqualTo []) then {
_pos = _target call cba_fnc_getPos;
_pos = _target call CBA_fnc_getPos;
};

// check if mod active
Expand Down
6 changes: 3 additions & 3 deletions addons/danger/functions/fnc_leaderAssess.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* success
*
* Example:
* [bob, getpos angryJoe] call lambs_danger_fnc_leaderAssess;
* [bob, getPos angryJoe] call lambs_danger_fnc_leaderAssess;
*
* Public: No
*/
Expand Down Expand Up @@ -49,9 +49,9 @@ private _enemy = _unit targets [true, 600, [], 0, _pos];
if !(_enemy isEqualTo []) then {

// Enemy is in buildings or at lower position
private _targets = _enemy findIf {_x isKindOf "Man" && { _x call FUNC(indoor) || {( getposASL _x select 2 ) < ( (getposASL _unit select 2) - 23) }}};
private _targets = _enemy findIf {_x isKindOf "Man" && { _x call FUNC(indoor) || {( getPosASL _x select 2 ) < ( (getPosASL _unit select 2) - 23) }}};
if (_targets != -1 && {!GVAR(disableAIAutonomousManoeuvres)}) then {
[_unit, 3, getposATL (_enemy select _targets)] call FUNC(leaderMode);
[_unit, 3, getPosATL (_enemy select _targets)] call FUNC(leaderMode);

// gesture
[_unit, ["gesturePoint"]] call FUNC(gesture);
Expand Down
2 changes: 1 addition & 1 deletion addons/danger/functions/fnc_leaderCQC.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* buildings found
*
* Example:
* [bob, getpos angryJoe] call lambs_danger_fnc_leaderCQC;
* [bob, getPos angryJoe] call lambs_danger_fnc_leaderCQC;
*
* Public: No
*/
Expand Down
2 changes: 1 addition & 1 deletion addons/danger/functions/fnc_leaderContact.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* success
*
* Example:
* [bob, getpos angryJoe] call lambs_danger_fnc_leaderAssess;
* [bob, getPos angryJoe] call lambs_danger_fnc_leaderAssess;
*
* Public: No
*/
Expand Down
8 changes: 4 additions & 4 deletions addons/danger/functions/fnc_leaderManoeuvre.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
params ["_unit", "_target", ["_units", []], ["_cycle", 3]];

// find target
_target = _target call cba_fnc_getPos;
_target = _target call CBA_fnc_getPos;

// stopped or static
if (!(attackEnabled _unit) || {stopped _unit}) exitWith {false};
Expand Down Expand Up @@ -52,11 +52,11 @@ if (_units isEqualTo []) then {
};

// find overwatch position
private _overwatch = [getpos _unit, ((_unit distance2d _target) / 2) min 300, 100, 8, _target] call FUNC(findOverwatch);
private _overwatch = [getPos _unit, ((_unit distance2d _target) / 2) min 300, 100, 8, _target] call FUNC(findOverwatch);

// sort building locations
private _pos = ([_target, 12, true, false] call FUNC(findBuildings));
[_pos, true] call cba_fnc_shuffle;
[_pos, true] call CBA_fnc_shuffle;
_pos pushBack _target;

// set tasks
Expand Down Expand Up @@ -108,7 +108,7 @@ private _fnc_manoeuvre = {
_fnc_manoeuvre,
[_cycle, _units, _pos, _fnc_manoeuvre],
12 + random 6
] call cba_fnc_waitAndExecute;
] call CBA_fnc_waitAndExecute;
};
};

Expand Down
2 changes: 1 addition & 1 deletion addons/danger/functions/fnc_react.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* success
*
* Example:
* [bob, getpos angryJoe, false] call lambs_danger_fnc_react;
* [bob, getPos angryJoe, false] call lambs_danger_fnc_react;
*
* Public: No
*/
Expand Down
2 changes: 1 addition & 1 deletion addons/danger/functions/fnc_shareInformation.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ if (GVAR(debug_functions)) then {
private _m = [_unit, "", _unit call FUNC(debugMarkerColor),"mil_dot"] call FUNC(dotMarker);
private _mt = [_target, "target", _target call FUNC(debugMarkerColor),"mil_dot"] call FUNC(dotMarker);
private _zm = [_unit, [_range,_range], _unit call FUNC(debugMarkerColor), "Border"] call FUNC(zoneMarker);
[{{deleteMarker _x;true} count _this;}, [_m, _mt, _zm], 60] call cba_fnc_waitAndExecute;
[{{deleteMarker _x;true} count _this;}, [_m, _mt, _zm], 60] call CBA_fnc_waitAndExecute;
};

// end
Expand Down
2 changes: 1 addition & 1 deletion addons/danger/functions/fnc_shareInformationRange.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ if (_radio) then {
_range = _range + GVAR(radio_Backpack);
};
// tweak by height above sea-level
_range = _range + (linearConversion [-200, 600, (getposASL _unit) select 2, -400, 1000, true]);
_range = _range + (linearConversion [-200, 600, (getPosASL _unit) select 2, -400, 1000, true]);

// return unit and range
[_target, _range, _radio]
4 changes: 2 additions & 2 deletions addons/danger/functions/fnc_suppress.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* success
*
* Example:
* [bob, getposASL angryJoe, false] call lambs_danger_fnc_suppress;
* [bob, getPosASL angryJoe, false] call lambs_danger_fnc_suppress;
*
* Public: No
*/
Expand Down Expand Up @@ -70,7 +70,7 @@ if (GVAR(debug_functions)) then {

private _sphere = createSimpleObject ["Sign_Sphere100cm_F", _pos, true];
_sphere setObjectTexture [0, [_unit] call FUNC(debugObjectColor)];
[{deleteVehicle _this}, _sphere, 20] call cba_fnc_waitAndExecute;
[{deleteVehicle _this}, _sphere, 20] call CBA_fnc_waitAndExecute;
};

// end
Expand Down
Loading