MeOS version 3.4.782
This commit is contained in:
parent
fefc6ac09e
commit
bb75f47626
@ -1688,7 +1688,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
else if (bi.id=="BrowseExport" || bi.id=="BrowseExportResult") {
|
||||
int filterIndex = gdi.getSelectedItem("Type").first;
|
||||
vector< pair<string, string> > ext;
|
||||
ImportFormats::getExportFilters(bi.id=="BrowseExport", ext);
|
||||
ImportFormats::getExportFilters(bi.id!="BrowseExport", ext);
|
||||
/*if (bi.id=="BrowseExport") {
|
||||
ext.push_back(make_pair("IOF Startlista (xml)", "*.xml"));
|
||||
ext.push_back(make_pair("OE Semikolonseparerad (csv)", "*.csv"));
|
||||
|
||||
@ -632,8 +632,16 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
||||
//We have a match!
|
||||
string club = gdi.getText("Club", true);
|
||||
|
||||
if (club.length()==0 && oe->getMeOSFeatures().hasFeature(MeOSFeatures::Clubs))
|
||||
club=lang.tl("Klubblös");
|
||||
if (club.length()==0 && oe->getMeOSFeatures().hasFeature(MeOSFeatures::Clubs)) {
|
||||
pClub noClub = oe->getClub(oe->getVacantClub(true));
|
||||
if (noClub) {
|
||||
noClub->synchronize();
|
||||
club = noClub->getName();
|
||||
}
|
||||
else
|
||||
club=lang.tl("Klubblös");
|
||||
}
|
||||
|
||||
int year = 0;
|
||||
pRunner r=gEvent->addRunner(gdi.getText("Runners"), club,
|
||||
classes[0]->getId(), activeSIC.CardNumber, year, true);
|
||||
@ -833,7 +841,7 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
||||
if (oe->getMeOSFeatures().hasFeature(MeOSFeatures::Clubs)) {
|
||||
string cname = gdi.getText("Club", true);
|
||||
|
||||
if (cname.empty()) {
|
||||
if (!cname.empty()) {
|
||||
pClub club = oe->getClubCreate(0, cname);
|
||||
clubId = club->getId();
|
||||
}
|
||||
@ -860,7 +868,8 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
||||
di.setInt("Fee", lastFeeNum);
|
||||
r->setFlag(oRunner::FlagFeeSpecified, true);
|
||||
|
||||
writePayMode(gdi, lastFeeNum + (cardFee > 0 ? cardFee : 0), *r);
|
||||
int totFee = lastFeeNum + (cardFee > 0 ? cardFee : 0);
|
||||
writePayMode(gdi, totFee, *r);
|
||||
|
||||
di.setString("Phone", gdi.getText("Phone"));
|
||||
r->setFlag(oRunner::FlagTransferSpecified, gdi.hasField("AllStages"));
|
||||
@ -897,6 +906,11 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
||||
if (r->getDI().getInt("Paid")>0)
|
||||
info += lang.tl(", Betalat") + pm;
|
||||
|
||||
bool warnPayment = r->getDI().getInt("Paid") < totFee && (
|
||||
r->getClubRef() == 0 ||
|
||||
r->getClubId() == oe->getVacantClubIfExist(true) ||
|
||||
r->getClubId() == oe->getVacantClubIfExist(false));
|
||||
|
||||
if (bib.length()>0)
|
||||
info+=bib;
|
||||
|
||||
@ -910,6 +924,10 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
||||
gdi.addStringUT(0, info, 0);
|
||||
gdi.popX();
|
||||
|
||||
if (warnPayment) {
|
||||
gdi.addString("", fontMediumPlus, "Varning: avgiften kan ej faktureras").setColor(colorRed);
|
||||
}
|
||||
|
||||
generateStartInfo(gdi, *r);
|
||||
|
||||
gdi.setRestorePoint("EntryLine");
|
||||
|
||||
@ -285,7 +285,7 @@ bool csvparser::ImportOE_CSV(oEvent &event, const char *file)
|
||||
pr = event.getRunner(id, 0);
|
||||
|
||||
while (pr) { // Check that the exact match is OK
|
||||
if (extId != pr->getExtIdentifier())
|
||||
if (extId == pr->getExtIdentifier())
|
||||
break;
|
||||
id++;
|
||||
pr = event.getRunner(id, 0);
|
||||
|
||||
@ -2239,3 +2239,4 @@ red channel = red channel
|
||||
blue channel = blue channel
|
||||
Printing failed (X: Y) Z = Printing failed (X: Y) Z
|
||||
prefsNameMode = Name format: 0 = 'Given Family', 1 = 'Family, Given'
|
||||
Varning: avgiften kan ej faktureras = Warning: cannot generate invoice for this fee
|
||||
|
||||
@ -1395,9 +1395,10 @@ pTeam IOF30Interface::getCreateTeam(gdioutput &gdi, const xmlobject &xTeam, bool
|
||||
|
||||
if (id)
|
||||
t = oe.getTeam(id);
|
||||
else
|
||||
else {
|
||||
t = oe.getTeamByName(name);
|
||||
|
||||
// XXX Check class
|
||||
}
|
||||
if (!t) {
|
||||
if (id > 0) {
|
||||
oTeam tr(&oe, id);
|
||||
@ -1628,7 +1629,7 @@ pRunner IOF30Interface::readPerson(gdioutput &gdi, const xmlobject &person) {
|
||||
if (pid) {
|
||||
r = oe.getRunner(pid, 0);
|
||||
while (r) { // Check that the exact match is OK
|
||||
if (extId != r->getExtIdentifier())
|
||||
if (extId == r->getExtIdentifier())
|
||||
break;
|
||||
pid++;
|
||||
r = oe.getRunner(pid, 0);
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
//V31: a
|
||||
//V33: abcde
|
||||
int getMeosBuild() {
|
||||
string revision("$Rev: 543 $");
|
||||
string revision("$Rev: 608 $");
|
||||
return 174 + atoi(revision.substr(5, string::npos).c_str());
|
||||
}
|
||||
|
||||
@ -38,14 +38,14 @@ int getMeosBuild() {
|
||||
//V31: abcde
|
||||
//V32: abcdefgh
|
||||
//V33: abcdefghij
|
||||
//V34: abcdfg
|
||||
//V34: abcdfgh
|
||||
string getMeosDate() {
|
||||
string date("$Date: 2017-03-25 20:00:02 +0100 (lö, 25 mar 2017) $");
|
||||
string date("$Date: 2017-08-27 21:13:26 +0200 (sö, 27 aug 2017) $");
|
||||
return date.substr(7,10);
|
||||
}
|
||||
|
||||
string getBuildType() {
|
||||
return ""; // No parantheses (...)
|
||||
return "U2"; // No parantheses (...)
|
||||
}
|
||||
|
||||
string getMajorVersion() {
|
||||
@ -169,4 +169,10 @@ void getSupporters(vector<string> &supp)
|
||||
supp.push_back("O-travel");
|
||||
supp.push_back("Bengt Bengtsson");
|
||||
supp.push_back("OK Landehof");
|
||||
supp.push_back("OK Orinto");
|
||||
supp.push_back("Bredaryds SOK");
|
||||
supp.push_back("Thore Nilsson, Uddevalla OK");
|
||||
supp.push_back("Timrå SOK");
|
||||
supp.push_back("Åke Larsson, OK Hedströmmen");
|
||||
supp.push_back("Avesta OK");
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ oClub::oClub(oEvent *poe, int id): oBase(poe)
|
||||
{
|
||||
getDI().initData();
|
||||
Id=id;
|
||||
if (id != cVacantId)
|
||||
if (id != cVacantId && id != cNoClubId)
|
||||
oe->qFreeClubId = max(id, oe->qFreeClubId);
|
||||
}
|
||||
|
||||
@ -191,8 +191,9 @@ pClub oEvent::getClubCreate(int Id, const string &CreateName)
|
||||
}
|
||||
}
|
||||
if (CreateName.empty()) {
|
||||
int id = oe->getVacantClub(true);
|
||||
//Not found. Auto add...
|
||||
return getClubCreate(Id, lang.tl("Klubblös"));
|
||||
return getClubCreate(id, lang.tl("Klubblös"));
|
||||
}
|
||||
else {
|
||||
oClubList::iterator it;
|
||||
@ -1053,7 +1054,7 @@ void oEvent::setupClubInfoData() {
|
||||
|
||||
|
||||
bool oClub::isVacant() const {
|
||||
return getId() == oe->getVacantClubIfExist();
|
||||
return getId() == oe->getVacantClubIfExist(false);
|
||||
}
|
||||
|
||||
void oClub::changeId(int newId) {
|
||||
|
||||
118
code/oEvent.cpp
118
code/oEvent.cpp
@ -116,6 +116,7 @@ oEvent::oEvent(gdioutput &gdi):oBase(0), gdibase(gdi)
|
||||
hMod=0;
|
||||
ZeroTime=0;
|
||||
vacantId = 0;
|
||||
noClubId = 0;
|
||||
dataRevision = 0;
|
||||
sqlCounterRunners=0;
|
||||
sqlCounterClasses=0;
|
||||
@ -1665,7 +1666,7 @@ pRunner oEvent::addRunner(const oRunner &r, bool updateStartNo) {
|
||||
}
|
||||
|
||||
pRunner oEvent::addRunnerVacant(int classId) {
|
||||
pRunner r=addRunner(lang.tl("Vakant"), getVacantClub(), classId, 0,0, true);
|
||||
pRunner r=addRunner(lang.tl("Vakant"), getVacantClub(false), classId, 0,0, true);
|
||||
if (r) {
|
||||
r->apply(false, 0, false);
|
||||
r->synchronize(true);
|
||||
@ -1771,7 +1772,7 @@ void oEvent::updateFreeId(oBase *obj)
|
||||
qFreeControlId=max(obj->Id, qFreeControlId);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oClub)){
|
||||
if (obj->Id != cVacantId)
|
||||
if (obj->Id != cVacantId && obj->Id != cNoClubId)
|
||||
qFreeClubId=max(obj->Id, qFreeClubId);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oCard)){
|
||||
@ -1822,7 +1823,7 @@ void oEvent::updateFreeId()
|
||||
oClubList::iterator it;
|
||||
qFreeClubId=0;
|
||||
for (it=Clubs.begin(); it != Clubs.end(); ++it) {
|
||||
if (it->Id != cVacantId)
|
||||
if (it->Id != cVacantId && it->Id != cNoClubId)
|
||||
qFreeClubId=max(qFreeClubId, it->Id);
|
||||
}
|
||||
}
|
||||
@ -1847,42 +1848,89 @@ void oEvent::updateFreeId()
|
||||
}
|
||||
}
|
||||
|
||||
int oEvent::getVacantClub()
|
||||
{
|
||||
if (vacantId > 0)
|
||||
int oEvent::getVacantClub(bool returnNoClubClub) {
|
||||
if (returnNoClubClub) {
|
||||
if (noClubId > 0) {
|
||||
pClub pc = getClub(noClubId);
|
||||
if (pc != 0 && !pc->isRemoved())
|
||||
return noClubId;
|
||||
}
|
||||
pClub pc = getClub("Klubblös");
|
||||
if (pc == 0)
|
||||
pc = getClub("No club"); //eng
|
||||
if (pc == 0)
|
||||
pc = getClub(lang.tl("Klubblös")); //other lang?
|
||||
|
||||
if (pc == 0)
|
||||
pc=getClubCreate(cNoClubId, lang.tl("Klubblös"));
|
||||
|
||||
noClubId = pc->getId();
|
||||
return noClubId;
|
||||
}
|
||||
else {
|
||||
if (vacantId > 0) {
|
||||
pClub pc = getClub(vacantId);
|
||||
if (pc != 0 && !pc->isRemoved())
|
||||
return vacantId;
|
||||
}
|
||||
pClub pc = getClub("Vakant");
|
||||
if (pc == 0)
|
||||
pc = getClub("Vacant"); //eng
|
||||
if (pc == 0)
|
||||
pc = getClub(lang.tl("Vakant")); //other lang?
|
||||
|
||||
if (pc == 0)
|
||||
pc=getClubCreate(cVacantId, lang.tl("Vakant"));
|
||||
|
||||
vacantId = pc->getId();
|
||||
return vacantId;
|
||||
|
||||
pClub pc = getClub("Vakant");
|
||||
if (pc == 0)
|
||||
pc = getClub("Vacant"); //eng
|
||||
if (pc == 0)
|
||||
pc = getClub(lang.tl("Vakant")); //other lang?
|
||||
|
||||
if (pc == 0)
|
||||
pc=getClubCreate(cVacantId, lang.tl("Vakant"));
|
||||
|
||||
vacantId = pc->getId();
|
||||
return vacantId;
|
||||
}
|
||||
}
|
||||
|
||||
int oEvent::getVacantClubIfExist() const
|
||||
int oEvent::getVacantClubIfExist(bool returnNoClubClub) const
|
||||
{
|
||||
if (vacantId > 0)
|
||||
return vacantId;
|
||||
if (vacantId == -1)
|
||||
return 0;
|
||||
pClub pc=getClub("Vakant");
|
||||
if (pc == 0)
|
||||
pc = getClub("Vacant");
|
||||
if (pc == 0)
|
||||
pc = getClub(lang.tl("Vakant")); //other lang?
|
||||
if (returnNoClubClub) {
|
||||
if (noClubId > 0) {
|
||||
pClub pc = getClub(noClubId);
|
||||
if (pc != 0 && !pc->isRemoved())
|
||||
return noClubId;
|
||||
}
|
||||
if (noClubId == -1)
|
||||
return 0;
|
||||
pClub pc=getClub("Klubblös");
|
||||
if (pc == 0)
|
||||
pc = getClub("Klubblös");
|
||||
if (pc == 0)
|
||||
pc = getClub(lang.tl("Klubblös")); //other lang?
|
||||
|
||||
if (!pc) {
|
||||
vacantId = -1;
|
||||
return 0;
|
||||
if (!pc) {
|
||||
noClubId = -1;
|
||||
return 0;
|
||||
}
|
||||
noClubId = pc->getId();
|
||||
return noClubId;
|
||||
}
|
||||
else {
|
||||
if (vacantId > 0) {
|
||||
pClub pc = getClub(vacantId);
|
||||
if (pc != 0 && !pc->isRemoved())
|
||||
return vacantId;
|
||||
}
|
||||
if (vacantId == -1)
|
||||
return 0;
|
||||
pClub pc=getClub("Vakant");
|
||||
if (pc == 0)
|
||||
pc = getClub("Vacant");
|
||||
if (pc == 0)
|
||||
pc = getClub(lang.tl("Vakant")); //other lang?
|
||||
|
||||
if (!pc) {
|
||||
vacantId = -1;
|
||||
return 0;
|
||||
}
|
||||
vacantId = pc->getId();
|
||||
return vacantId;
|
||||
}
|
||||
vacantId = pc->getId();
|
||||
return vacantId;
|
||||
}
|
||||
|
||||
pCard oEvent::allocateCard(pRunner owner)
|
||||
@ -2417,6 +2465,9 @@ void oEvent::removeClub(int Id)
|
||||
}
|
||||
if (vacantId == Id)
|
||||
vacantId = 0; // Clear vacant id
|
||||
|
||||
if (noClubId == Id)
|
||||
noClubId = 0;
|
||||
}
|
||||
|
||||
void oEvent::removeCard(int Id)
|
||||
@ -3371,6 +3422,7 @@ void oEvent::clear()
|
||||
sqlUpdateTeams.clear();
|
||||
|
||||
vacantId = 0;
|
||||
noClubId = 0;
|
||||
oEventData->initData(this, sizeof(oData));
|
||||
timelineClasses.clear();
|
||||
timeLineEvents.clear();
|
||||
|
||||
@ -50,6 +50,7 @@
|
||||
#include <hash_map>
|
||||
|
||||
#define cVacantId 888888888
|
||||
#define cNoClubId 999999999
|
||||
|
||||
class MeOSFileLock;
|
||||
class RunnerDB;
|
||||
@ -237,10 +238,9 @@ protected:
|
||||
void generateFixedList(gdioutput &gdi, const oListInfo &li);
|
||||
|
||||
void startReconnectDaemon();
|
||||
int getVacantClub(); // Create vacant club if it does not exist
|
||||
int getVacantClubIfExist() const;
|
||||
|
||||
mutable int vacantId; //Cached vacant id
|
||||
mutable int noClubId; //Cached no club id
|
||||
|
||||
string Name;
|
||||
string Annotation;
|
||||
@ -473,6 +473,9 @@ protected:
|
||||
bool disableRecalculate;
|
||||
public:
|
||||
|
||||
int getVacantClub(bool returnNoClubClub); // Create vacant club if it does not exist
|
||||
int getVacantClubIfExist(bool returnNoClubClub) const;
|
||||
|
||||
enum NameMode {
|
||||
FirstLast,
|
||||
LastFirst,
|
||||
|
||||
@ -673,7 +673,7 @@ void oEvent::drawList(const vector<ClassDrawSpecification> &spec,
|
||||
assert(pairSize > 0);
|
||||
oRunnerList::iterator it;
|
||||
|
||||
int VacantClubId=getVacantClub();
|
||||
int VacantClubId=getVacantClub(false);
|
||||
map<int, int> clsId2Ix;
|
||||
set<int> clsIdClearVac;
|
||||
|
||||
|
||||
@ -2536,12 +2536,12 @@ void oEvent::generateListInternal(gdioutput &gdi, const oListInfo &li, bool form
|
||||
continue;
|
||||
|
||||
if (li.filter(EFilterVacant)) {
|
||||
if (it->getId() == getVacantClub())
|
||||
if (it->getId() == getVacantClub(false))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (li.filter(EFilterOnlyVacant)) {
|
||||
if (it->getId() != getVacantClub())
|
||||
if (it->getId() != getVacantClub(false))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -340,7 +340,7 @@ void oEvent::generatePreReport(gdioutput &gdi) {
|
||||
CurrentSortOrder=SortByName;
|
||||
Runners.sort();
|
||||
|
||||
int lVacId = getVacantClub();
|
||||
int lVacId = getVacantClub(false);
|
||||
|
||||
oRunnerList::iterator r_it;
|
||||
oTeamList::iterator t_it;
|
||||
|
||||
@ -2694,7 +2694,7 @@ const vector< pair<string, size_t> > &oEvent::fillRunners(vector< pair<string, s
|
||||
|
||||
synchronizeList(oLRunnerId);
|
||||
oRunnerList::iterator it;
|
||||
int lVacId = getVacantClub();
|
||||
int lVacId = getVacantClubIfExist(false);
|
||||
if (getNameMode() == LastFirst)
|
||||
CurrentSortOrder = SortByLastName;
|
||||
else
|
||||
@ -2742,7 +2742,7 @@ const vector< pair<string, size_t> > &oEvent::fillRunners(vector< pair<string, s
|
||||
continue;
|
||||
|
||||
if (!it->skip() || (showAll && !it->isRemoved())) {
|
||||
if ( it->getClubId() != lVacId )
|
||||
if ( it->getClubId() != lVacId || lVacId == 0)
|
||||
out.push_back(make_pair(it->getUIName(), it->Id));
|
||||
else {
|
||||
sprintf_s(bf, "%s (%s)", it->getUIName().c_str(), it->getClass().c_str());
|
||||
@ -3328,7 +3328,7 @@ string oRunner::getPunchTimeS(int controlNumber, bool normalized) const
|
||||
|
||||
bool oAbstractRunner::isVacant() const
|
||||
{
|
||||
return getClubId()==oe->getVacantClubIfExist();
|
||||
return getClubId()==oe->getVacantClubIfExist(false);
|
||||
}
|
||||
|
||||
bool oRunner::needNoCard() const {
|
||||
|
||||
@ -645,13 +645,16 @@ void PageInfo::renderPages(const list<TextInfo> &tl,
|
||||
const TextInfo &text = *it;
|
||||
if (text.format == 10)
|
||||
continue;
|
||||
if (text.format != pageNewPage && text.format != pagePageInfo) {
|
||||
if (currentYP > text.yp) {
|
||||
needSort = true;
|
||||
}
|
||||
|
||||
if (currentYP > text.yp) {
|
||||
needSort = true;
|
||||
minX = min(minX, (float)it->textRect.left);
|
||||
top = min(top, text.yp);
|
||||
}
|
||||
minX = min(minX, (float)it->textRect.left);
|
||||
top = min(top, text.yp);
|
||||
currentYP = text.yp;
|
||||
|
||||
indexedTL.push_back(PrintItemInfo(currentYP, &text));
|
||||
}
|
||||
|
||||
|
||||
@ -2239,3 +2239,4 @@ red channel = r
|
||||
blue channel = blå kanal
|
||||
Printing failed (X: Y) Z = Utskrift misslyckades (X: Y) Z
|
||||
prefsNameMode = Namnformat: 0 = 'Förnamn Efternamn', 1 = 'Efternamn, Förnamn'
|
||||
Varning: avgiften kan ej faktureras = Varning: avgiften kan ej faktureras
|
||||
|
||||
@ -717,9 +717,9 @@ string &xmlobject::getObjectString(const char *pname, string &out) const
|
||||
{
|
||||
xmlobject x=getObject(pname);
|
||||
if (x) {
|
||||
const char *bf = x.get();
|
||||
const char *bf = x.getRaw();
|
||||
if (bf) {
|
||||
parser->convertString(x.get(), parser->strbuff, buff_pre_alloc);
|
||||
parser->convertString(x.getRaw(), parser->strbuff, buff_pre_alloc);
|
||||
out = parser->strbuff;
|
||||
return out;
|
||||
}
|
||||
@ -740,7 +740,7 @@ char *xmlobject::getObjectString(const char *pname, char *out, int maxlen) const
|
||||
{
|
||||
xmlobject x=getObject(pname);
|
||||
if (x) {
|
||||
const char *bf = x.get();
|
||||
const char *bf = x.getRaw();
|
||||
if (bf) {
|
||||
parser->convertString(bf, out, maxlen);
|
||||
return out;
|
||||
@ -757,6 +757,28 @@ char *xmlobject::getObjectString(const char *pname, char *out, int maxlen) const
|
||||
return out;
|
||||
}
|
||||
|
||||
const char *xmlobject::get() const
|
||||
{
|
||||
const char *ptr = getRaw();
|
||||
if (ptr == 0)
|
||||
return 0;
|
||||
static char buff[buff_pre_alloc];
|
||||
if (parser->isUTF) {
|
||||
int len = strlen(ptr);
|
||||
len = min(len+1, buff_pre_alloc-10);
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, ptr, len, parser->strbuffw, buff_pre_alloc);
|
||||
parser->strbuffw[wlen-1] = 0;
|
||||
for (int k = 0; k< wlen; k++) {
|
||||
buff[k] = parser->strbuffw[k] & 0xFF;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return ptr;
|
||||
}
|
||||
return buff;
|
||||
}
|
||||
|
||||
|
||||
const char *xmlattrib::get() const
|
||||
{
|
||||
if (data)
|
||||
|
||||
@ -103,6 +103,7 @@ protected:
|
||||
|
||||
bool isUTF;
|
||||
char strbuff[buff_pre_alloc]; // Temporary buffer for processing (no threading allowed)
|
||||
wchar_t strbuffw[buff_pre_alloc]; // Temporary buffer for processing (no threading allowed)
|
||||
|
||||
ProgressWindow *progress;
|
||||
int lastIndex;
|
||||
@ -204,7 +205,8 @@ public:
|
||||
return n[0] == pname[0] && strcmp(n, pname)==0;
|
||||
}
|
||||
|
||||
const char *get() const {return parser->xmlinfo[index].data;}
|
||||
const char *getRaw() const {return parser->xmlinfo[index].data;}
|
||||
const char *get() const;
|
||||
int getInt() const {const char *d = parser->xmlinfo[index].data;
|
||||
return d ? atoi(d) : 0;}
|
||||
__int64 getInt64() const {const char *d = parser->xmlinfo[index].data;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user