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

Fully localize all user visible actions, messages, notifications and fix related bugs #96

Merged
merged 55 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
631eec0
Replace placeholders
3Mydlo3 Jan 28, 2024
ad3f900
Variable location size so kill messages better reflect in/around for …
3Mydlo3 Jan 28, 2024
f743cc8
Merge remote-tracking branch 'origin/master' into feature/localize-ki…
3Mydlo3 Mar 22, 2024
2cb8959
Adjust for cityArea
3Mydlo3 Mar 22, 2024
83e45de
Fix Civilian killed stringtable
3Mydlo3 Mar 27, 2024
4c219e3
Optimize killed marker creation
3Mydlo3 Mar 27, 2024
bdcbf3b
Prevent 'cop killed by cop' when civilian kills cop
3Mydlo3 Mar 27, 2024
7d15f7e
Fix localization of kill notifications
3Mydlo3 Mar 27, 2024
b3caccb
Show localized car alarm notification
3Mydlo3 Mar 27, 2024
be4d353
Localize cannot create vehicle message
3Mydlo3 Mar 27, 2024
196f8ec
Fix some settings should not require restart
3Mydlo3 Mar 28, 2024
5ee9b37
Fix alarm not working in nearby civilians mode
3Mydlo3 Mar 28, 2024
79e77d9
Add TODO
3Mydlo3 Mar 28, 2024
257cec8
Merge remote-tracking branch 'origin/master' into feature/localize-me…
3Mydlo3 Apr 4, 2024
12465fb
Localize killers start positions names
3Mydlo3 Apr 4, 2024
b3b664d
Fix incorrect PREP
3Mydlo3 Apr 4, 2024
af277ff
Change locationNames(Raw) namespaces to hashMaps
3Mydlo3 Apr 4, 2024
d991536
Fix default LocationName for module not being localized
3Mydlo3 Apr 4, 2024
4e72f39
Fix for generated positions
3Mydlo3 Apr 4, 2024
3839528
Optimize policeStationMarker creation
3Mydlo3 Apr 4, 2024
cbba9ed
Localize "Teleport back"
3Mydlo3 Apr 4, 2024
b96c00d
Add FUNC(isCop)
3Mydlo3 Apr 5, 2024
6c67ed9
Fix logging player or AI
3Mydlo3 Apr 5, 2024
2bb795f
Fix again
3Mydlo3 Apr 5, 2024
03984cc
Fix side check in isCop
3Mydlo3 Apr 5, 2024
43cc417
Try workaround for vehicle suicide detection
3Mydlo3 Apr 6, 2024
3eb5190
Add name of the cop that killed other cop
3Mydlo3 Apr 6, 2024
61d79d9
Fix variable name
3Mydlo3 Apr 6, 2024
7346c3a
Fix cop check in kill messages
3Mydlo3 Apr 6, 2024
c059d01
Fix killer name being null on suicide
3Mydlo3 Apr 6, 2024
dece8c3
Resolve TODO
3Mydlo3 Apr 6, 2024
58faad2
Localized police station name
3Mydlo3 Apr 7, 2024
8acee09
Fix no empty spawner message appearing when empty vehicle can be removed
3Mydlo3 Apr 7, 2024
574a5a0
Increase 2nd spawn attempt delay
3Mydlo3 Apr 7, 2024
aeddb90
Remove forced police station names from missions
3Mydlo3 Apr 7, 2024
cc2a95f
Add a note to module "LocationName" that it's optional
3Mydlo3 Apr 7, 2024
1228446
Fix killers start module missing property name
3Mydlo3 Apr 7, 2024
f907865
Drop forced killers start name in Malden scenario
3Mydlo3 Apr 7, 2024
69780ee
Log module LocationNames and fix automatic name selection
3Mydlo3 Apr 7, 2024
8a6bc66
Fix killers don't see police station markers
3Mydlo3 Apr 8, 2024
0a11386
Merge remote-tracking branch 'origin/master' into feature/full-locali…
3Mydlo3 Apr 8, 2024
79701bb
Try localize 'maximum idle time reached'
3Mydlo3 Apr 8, 2024
59fbd1b
Localize teleport name
3Mydlo3 Apr 9, 2024
a50935f
Use isNotEqualTo
3Mydlo3 Apr 9, 2024
f2d95b9
PublicVariable LocationName of police station module
3Mydlo3 Apr 9, 2024
bb9e205
Pass unlocalized string to changeScore for timeout message
3Mydlo3 Apr 9, 2024
0b705b2
Fix localizable message template and args ignored in showScore flow
3Mydlo3 Apr 9, 2024
ae60cc0
Still doesn't work
3Mydlo3 Apr 9, 2024
c51d3d3
Fix format array creation
3Mydlo3 Apr 13, 2024
d9f9da9
Add postInit warning message that debug mode is enabled
3Mydlo3 Apr 13, 2024
f6affbb
Actually implement time limit
3Mydlo3 Apr 13, 2024
f048ecb
Change killers score change stacking duration the more score changes
3Mydlo3 Apr 13, 2024
f1f32d8
Time limit & extra time improvements
3Mydlo3 Apr 13, 2024
bca0f02
Shorten main game time limit to 30 minutes (+15 extra)
3Mydlo3 Apr 13, 2024
00b05b0
Increase extra time timeouts limit
3Mydlo3 Apr 13, 2024
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
1 change: 1 addition & 0 deletions addons/civilian/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ PREP(initCity);
PREP(initCivilians);
PREP(initConfig);
PREP(initCivilian);
PREP(isPositionInCity);
PREP(unassignCivilianFromCity);
5 changes: 5 additions & 0 deletions addons/civilian/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ if (isServer) then {
_this call FUNC(civilianKilled);
}] call CBA_fnc_addEventHandler;
};

[QGVAR(showCivilianKilledNotification), {
private _msg = _this call FUNC(civilianKilledMsg);
[QEGVAR(common,showSideChatMsg), [WEST, _msg]] call CBA_fnc_localEvent;
}] call CBA_fnc_addEventHandler;
11 changes: 5 additions & 6 deletions addons/civilian/functions/fnc_civilianKilled.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,15 @@ private _time = [daytime] call BIS_fnc_timeToString;
// Call function to create marker at killed unit's position.
[_civilian, _time] call FUNC(civilianKilledMarker);
// Show message for all cops that cop has been killed near some location with timestamp
private _msg = [_civilian, _time] call FUNC(civilianKilledMsg);
[QEGVAR(common,showSideChatMsg), [WEST, _msg]] call CBA_fnc_globalEvent;
[QGVAR(showCivilianKilledNotification), [_civilian, _killer, _time]] call CBA_fnc_globalEvent;

// Killer can be vehicle sometimes so get driver
_killer = driver _killer;
// If killer was police, we need to change score accordingly
if (side _killer isEqualTo WEST) then {
[QEGVAR(score,changeScore), [EAST, EGVAR(score,policekilledCivilianKillersScore), "CIVILIAN KILLED BY COP PLACEHOLDER"]] call CBA_fnc_serverEvent;
[QEGVAR(score,changeScore), [WEST, EGVAR(score,policeKilledCivilianPoliceScore), "CIVILIAN KILLED BY COP PLACEHOLDER"]] call CBA_fnc_serverEvent;
[QEGVAR(score,changeScore), [EAST, EGVAR(score,policekilledCivilianKillersScore), LSTRING(KilledByCop)]] call CBA_fnc_serverEvent;
[QEGVAR(score,changeScore), [WEST, EGVAR(score,policeKilledCivilianPoliceScore), LSTRING(KilledByCop)]] call CBA_fnc_serverEvent;
} else {
[QEGVAR(score,changeScore), [EAST, EGVAR(score,killedCivilianKillersScore), "CIVILIAN KILLED PLACEHOLDER"]] call CBA_fnc_serverEvent;
[QEGVAR(score,changeScore), [WEST, EGVAR(score,killedCivilianPoliceScore), "CIVILIAN KILLED PLACEHOLDER"]] call CBA_fnc_serverEvent;
[QEGVAR(score,changeScore), [EAST, EGVAR(score,killedCivilianKillersScore), LSTRING(Killed)]] call CBA_fnc_serverEvent;
[QEGVAR(score,changeScore), [WEST, EGVAR(score,killedCivilianPoliceScore), LSTRING(Killed)]] call CBA_fnc_serverEvent;
};
8 changes: 4 additions & 4 deletions addons/civilian/functions/fnc_civilianKilledMarker.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ params ["_unit", "_time"];

private _markerName = format ["killed_civilian_%1_%2", _unit];
private _markerText = format ["%1", _time];
private _marker = createMarker [_markerName, getPosATL _unit];
_marker setMarkerType "mil_objective";
_marker setMarkerColor "ColorEAST";
_marker setMarkerSize [0.4, 0.4];
private _marker = createMarkerLocal [_markerName, getPosATL _unit];
_marker setMarkerTypeLocal "mil_objective";
_marker setMarkerColorLocal "ColorEAST";
_marker setMarkerSizeLocal [0.4, 0.4];
_marker setMarkerText _markerText;

[_marker] call EFUNC(markers,markerDecay);
Expand Down
26 changes: 10 additions & 16 deletions addons/civilian/functions/fnc_civilianKilledMsg.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
*
* Arguments:
* 0: Dead civilian <OBJECT>
* 1: Civilian's time of death <STRING>
* 2: Nearest location <LOCATION>
* 1: Unit which killed civilian <OBJECT>
* 2: Civilian's time of death <STRING>
* 3: Nearest location <LOCATION>
*
* Return Value:
* 0: Civilian killed message <STRING>
Expand All @@ -17,27 +18,20 @@
* Public: No
*/

params ["_deadCivilian", ["_timeOfDeath", daytime], ["_nearestTown", locationNull]];
params ["_unit", ["_killer", objNull], ["_timeOfDeath", daytime], ["_nearestTown", locationNull]];

if (_timeOfDeath isEqualType 0) then {
_timeOfDeath = [_timeOfDeath] call BIS_fnc_timeToString;
};

private _nearestCity = if (isNull _nearestTown) then {
[_deadCivilian] call FUNC(getNearestCity)
// Check if civilian died in city. If so then change output a bit to represent that.
private _template = if ([_unit, _nearestTown] call FUNC(isPositionInCity)) then {
if ([_killer] call EFUNC(police,isCop)) then { LLSTRING(KilledByCop_In_City) } else { LLSTRING(Killed_In_City) };
} else {
[_nearestTown] call FUNC(getCityByLocation)
if ([_killer] call EFUNC(police,isCop)) then { LLSTRING(KilledByCop_Near_City) } else { LLSTRING(Killed_Near_City) };
};

private _msg = "";
private _nearestCityArea = _nearestCity getVariable QGVAR(cityArea);
private _isInCity = (position _deadCivilian) inArea _nearestCityArea;

// Check if distance is greater than 250 m. If so then change output a bit to represent that.
if (_isInCity) then {
_msg = format [LLSTRING(Civilian_Killed_In_City), _timeOfDeath, text _nearestTown];
} else {
_msg = format [LLSTRING(Civilian_Killed_Near_City), _timeOfDeath, text _nearestTown];
};
// Supplying killer name to format, but only killed by cop should reveal name for lynch
private _msg = format [_template, _timeOfDeath, text _nearestTown, name _killer];

_msg
32 changes: 32 additions & 0 deletions addons/civilian/functions/fnc_isPositionInCity.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "script_component.hpp"
/*
* Author: 3Mydlo3
* Function checks if a unit/position is in a city.
*
* Arguments:
* 0: Unit/Position to check <OBJECT/POSITION>
* 1: Particular city location to check <LOCATION> (Optional)
*
* Return Value:
* 0: Result <BOOL>
*
* Example:
* [position player] call afsk_civilian_fnc_isPositionInCity
*
* Public: No
*/

params ["_position", ["_location", locationNull]];

if (_position isEqualType objNull) then {
_position = getPosATL _position;
};

private _nearestCity = if (_location isEqualTo locationNull) then {
[_position] call FUNC(getNearestCity)
} else {
[_location] call FUNC(getCityByLocation)
};

private _nearestCityArea = _nearestCity getVariable QGVAR(cityArea);
_position inArea _nearestCityArea
28 changes: 26 additions & 2 deletions addons/civilian/stringtable.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,30 @@
<English>SerialKillers - Civilian</English>
<Polish>SerialKillers - Cywile</Polish>
</Key>
<Key ID="STR_AFSK_Civilian_Civilian_Killed_In_City">
<Key ID="STR_AFSK_Civilian_EmptyVehiclesLimit">
<English>Civilian vehicles limit</English>
<Polish>Limit pojazdów cywilnych</Polish>
</Key>
<Key ID="STR_AFSK_Civilian_EmptyVehiclesLimit_Description">
<English>Controls how much civilian vehicles will be created on the whole map.</English>
<Polish>Ustala jak dużo pojazdów cywilnych będzie utworzonych na całej mapie.</Polish>
</Key>
<Key ID="STR_AFSK_Civilian_Killed_In_City">
<English>Civilian was killed at %1 in %2!</English>
<Polish>Cywil został zabity o godzinie %1 w %2!</Polish>
</Key>
<Key ID="STR_AFSK_Civilian_Civilian_Killed_Near_City">
<Key ID="STR_AFSK_Civilian_Killed_Near_City">
<English>Civilian was killed at %1 near %2!</English>
<Polish>Cywil został zabity o godzinie %1 w pobliżu %2!</Polish>
</Key>
<Key ID="STR_AFSK_Civilian_KilledByCop_In_City">
<English>Civilian was killed by cop %3 at %1 in %2!</English>
<Polish>Cywil został zabity przez policjanta %3 o godzinie %1 w %2!</Polish>
</Key>
<Key ID="STR_AFSK_Civilian_KilledByCop_Near_City">
<English>Civilian was killed by cop %3 at %1 near %2!</English>
<Polish>Cywil został zabity przez policjanta %3 o godzinie %1 w pobliżu %2!</Polish>
</Key>
<Key ID="STR_AFSK_Civilian_InitialCiviliansCount">
<English>Civilians count</English>
<Polish>Liczba cywili</Polish>
Expand Down Expand Up @@ -89,6 +105,14 @@
<English>When map locations are badly defined, this can be used to control how large capital(s) are on a given map. This is used for spawning civilians, waypoints and some other things.</English>
<Polish>Gdy lokacje na mapie są słabo zdefiniowane, można ustawić ręcznie jak duże są stolice na danej mapie. Jest to używane do spawnownia cywili, waypointów i wielu innych rzeczy.</Polish>
</Key>
<Key ID="STR_AFSK_Civilian_Killed">
<English>Civilian was killed</English>
<Polish>Cywil został zabity</Polish>
</Key>
<Key ID="STR_AFSK_Civilian_KilledByCop">
<English>Civilian was killed by cop</English>
<Polish>Cywil został zabity przez policjanta</Polish>
</Key>
<Key ID="STR_AFSK_Civilian_Low">
<English>Low</English>
<Polish>Mało</Polish>
Expand Down
1 change: 1 addition & 0 deletions addons/common/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ PREP(createArsenal);
PREP(deleteAtRandom);
PREP(getAllMapCities);
PREP(getLocationName);
PREP(getLocationNameRaw);
PREP(getLocationType);
PREP(getNearestCityLocation);
PREP(getNearestLocation);
Expand Down
8 changes: 6 additions & 2 deletions addons/common/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include "script_component.hpp"

#ifdef DEBUG_MODE_FULL
WARNING("Debug mode is enabled. It might reveal information, don't use it for normal gameplay!");
#endif

// Killswitch
if (!EGVAR(common,enabled)) exitWith {
WARNING("Mission is missing 'SK' gameType Header. SerialKillers framework will be disabled.");
Expand All @@ -19,7 +23,7 @@ if (isServer) then {
params [["_side", sideEmpty], ["_msg", ""]];
if (_msg isEqualTo "") exitWith {};
private _sideText = if (_side isEqualTo sideEmpty) then { "ALL" } else { _side };
INFO_2("(Side Chat) %1: %2",_sideText,_msg);
INFO_2("(Side Chat) %1: %2",_sideText,_msg call BIS_fnc_localize);
}] call CBA_fnc_addEventHandler;
};

Expand Down Expand Up @@ -60,7 +64,7 @@ if (hasInterface) then {
if (_msg isEqualTo "") exitWith {};
// If side is empty we want to show message to everyone
if (_side isEqualTo sideEmpty || {playerSide isEqualTo _side}) then {
[playerSide, "HQ"] sideChat _msg;
[playerSide, "HQ"] sideChat (_msg call BIS_fnc_localize);
};
}] call CBA_fnc_addEventHandler;
};
3 changes: 2 additions & 1 deletion addons/common/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ if (!GVAR(enabled)) exitWith {};
GVAR(allLocationTypes) = ("true" configClasses (configFile >> "CfgLocationTypes")) apply {configName _x};

// Location names cache namespace (to prevent reading from config every time)
GVAR(locationNames) = call CBA_fnc_createNamespace;
GVAR(locationNames) = createHashMap;
GVAR(locationNamesRaw) = createHashMap;

if (isServer) then {
GVAR(musicEH) = -1;
Expand Down
4 changes: 2 additions & 2 deletions addons/common/functions/fnc_getLocationName.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ private _locationClassname = if (_location isEqualType locationNull) then {
if (_locationClassname isEqualTo "") exitWith {""};

// Try to get name from cache
private _name = GVAR(locationNames) getVariable [_locationClassname, ""];
private _name = GVAR(locationNames) getOrDefault [_locationClassname, ""];

if (_name isEqualTo "") then {
_name = getText (configFile >> "CfgWorlds" >> worldName >> "Names" >> _locationClassname >> "name");
// Fill cache
GVAR(locationNames) setVariable [_locationClassname, _name];
GVAR(locationNames) set [_locationClassname, _name];
};

_name
38 changes: 38 additions & 0 deletions addons/common/functions/fnc_getLocationNameRaw.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "script_component.hpp"
/*
* Author: 3Mydlo3
* Function returns location name from config.
*
* Arguments:
* 0: Location <LOCATION>
*
* Return Value:
* 0: Location name <STRING>
*
* Example:
* [[player] call afsk_common_fnc_getNearestLocation] call afsk_common_fnc_getLocationName
*
* Public: No
*/

params ["_location"];

private _locationClassname = if (_location isEqualType locationNull) then {
className _location;
} else {
_location
};

// Location does not have classname so no name also
if (_locationClassname isEqualTo "") exitWith {""};

// Try to get name from cache
private _name = GVAR(locationNamesRaw) getOrDefault [_locationClassname, ""];

if (_name isEqualTo "") then {
_name = getTextRaw (configFile >> "CfgWorlds" >> worldName >> "Names" >> _locationClassname >> "name");
// Fill cache
GVAR(locationNamesRaw) set [_locationClassname, _name];
};

_name
2 changes: 1 addition & 1 deletion addons/killers/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ if (hasInterface) then {

[QGVAR(teleportedToStart), {
params ["_flag"];
private _actionID = player addAction ["Teleport back", {
private _actionID = player addAction [LLSTRING(TeleportBack), {
player setPos getPosATL (_this select 3)
}, _flag, 10, true];
// Wait until player teleports back or times out
Expand Down
2 changes: 1 addition & 1 deletion addons/killers/functions/fnc_createTeleport.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ private _teleportActionsIDs = [];
private _positionID = 0;
{
// _x is location name and value is position assigned
private _destinationName = format ["%1 - %2", _positionID, _x];
private _destinationName = format ["%1 - %2", _positionID, localize _x];
private _destinationPos = GVAR(startPositions) getVariable _x;
private _teleportActionID = _flag addAction [_destinationName, {
[QEGVAR(killers,teleport), [_this select 1, _this select 3 select 0]] call CBA_fnc_localEvent;
Expand Down
5 changes: 3 additions & 2 deletions addons/killers/functions/fnc_initStartPositions.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ while {_i > 0} do {
private _nearestLocation = [_pos, 1500] call EFUNC(common,getNearestLocationWithAvailableName);
//diag_log format ["[AFSK] [KILLERS] [initStartPositions] Location: %1", _nearestLocation];
if (_nearestLocation isEqualTo locationNull) exitWith {};
private _locationName = [_nearestLocation] call EFUNC(common,getLocationName);
private _locationName = [_nearestLocation] call EFUNC(common,getLocationNameRaw);
if (_locationName isEqualTo "") exitWith {};
//diag_log format ["[AFSK] [KILLERS] [initStartPositions] Location Name: %1", _locationName];
if (!(_positions getVariable [_locationName, []] isEqualTo [])) exitWith {};
Expand All @@ -45,12 +45,13 @@ while {_i > 0} do {
{
private _pos = getPos _x;
private _locationName = _x getVariable ["LocationName", ""];
// TODO: Localize location name (move it to local rather than server)
if (_locationName isEqualTo "") then {
private _nearestLocation = [_pos] call EFUNC(common,getNearestLocationWithAvailableName);
_locationName = if (_nearestLocation isEqualTo locationNull) then {
random (999) toFixed 1
} else {
[_nearestLocation] call EFUNC(common,getLocationName);
[_nearestLocation] call EFUNC(common,getLocationNameRaw);
};
};
_positions setVariable [_locationName, _pos, true];
Expand Down
4 changes: 4 additions & 0 deletions addons/killers/stringtable.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,9 @@
<English>How many positions will be available to killers for teleportation on the beginning. 0 or -1 to random [10, 20].</English>
<Polish>Ile pozycji do teleportacji na starcie będzie dostępnych dla zabójców. 0 lub -1 by wylosować z przedziału [10, 20]</Polish>
</Key>
<Key ID="STR_AFSK_Killers_TeleportBack">
<English>Teleport back</English>
<Polish>Teleport z powrotem</Polish>
</Key>
</Package>
</Project>
2 changes: 1 addition & 1 deletion addons/main/script_mod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#define VERSION_STR MAJOR.MINOR.PATCH.BUILD
#define VERSION_AR MAJOR,MINOR,PATCH,BUILD

#define REQUIRED_VERSION 1.94
#define REQUIRED_VERSION 2.08

#ifdef COMPONENT_BEAUTIFIED
#define COMPONENT_NAME QUOTE(AFSK - COMPONENT_BEAUTIFIED)
Expand Down
6 changes: 3 additions & 3 deletions addons/missions/SK_test.Malden/mission.sqm
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class Mission
"STRING"
};
};
value="Chapoi";
value="";
};
};
};
Expand Down Expand Up @@ -255,7 +255,7 @@ class Mission
"STRING"
};
};
value="Le Port";
value="";
};
};
};
Expand Down Expand Up @@ -552,7 +552,7 @@ class Mission
"STRING"
};
};
value="Kankon";
value="";
};
};
};
Expand Down
Loading