Bearbeiten von „OS2.jugend

Zur Navigation springen Zur Suche springen
Warnung: Du bist nicht angemeldet. Deine IP-Adresse wird bei Bearbeitungen öffentlich sichtbar. Melde dich an oder erstelle ein Benutzerkonto, damit Bearbeitungen deinem Benutzernamen zugeordnet werden. Ein eigenes Benutzerkonto hat eine ganze Reihe von Vorteilen.

Die Bearbeitung kann rückgängig gemacht werden. Bitte prüfe den Vergleich unten, um sicherzustellen, dass du dies tun möchtest, und veröffentliche dann unten deine Änderungen, um die Bearbeitung rückgängig zu machen.

Aktuelle Version Dein Text
Zeile 8: Zeile 8:
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
| '''Version'''
| '''Version'''
| '''0.73 (WebExtensions)'''
| '''0.70 (WebExtensions)'''
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
| '''Autor'''
| '''Autor'''
Zeile 36: Zeile 36:
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
| '''Funktionalität'''
| '''Funktionalität'''
| '''Trennstriche zwischen den Jahrgängen'''<br> '''Aktueller Skill, Opti und MW'''<br> '''Prognose von Opti und MW für Ende Jahrgang 18'''<br> '''Optionen und Menu'''<br> '''Neue Marktwertformel'''<br> '''Automatische Ermittlung des ZATs'''<br> '''Hidden-Optionen und Datenspeicher'''<br> '''Geburtstage und dezimales Alter'''<br> '''Erweiterte Optionen auch auf der Seite'''<br> '''Zusatzspalten Talent/Quote/Aufw./Geb./Alter'''<br> '''Zusatzspalten Quote/Alter/Pos in der Übersicht'''<br> '''Zusatzspalten Alter ersetzen/Aufwertungen kurz+TOR'''<br> '''Zusatzspalten fix/tr./%H/%N/Prios jetzt und Ende'''<br> '''Interaktive Menü-Optionen'''<br> '''Gemeinsame Code- und Datenbasis'''<br> '''Qualitätsbalken'''<br> '''Markierung der Primärskills bei Einzelwerten und Aufwertungen'''<br> '''Beachtung von Jugendförderung und Doppelpositionen'''<br> '''Warnung vor Ende 18 in letzter Periode und mehr am letzten ZAT'''<br> '''Reguläre Ausdrücke im @include'''<br> '''Neues Design und Seite "Opt. Skill"'''<br> '''Gruppierung nach Jahrgängen U13 bis U18 (per Option)'''<br> '''Warnung vor Ende 18 auch im Managerbüro (per Option)'''<br> '''Warnung vor Sperre des Ziehens im Falle eines Aufstiegs'''<br> '''Neuer Jahrgang U19'''
| '''Trennstriche zwischen den Jahrgängen'''<br> '''Aktueller Skill, Opti und MW'''<br> '''Prognose von Opti und MW für Ende Jahrgang 18'''<br> '''Optionen und Menu'''<br> '''Neue Marktwertformel'''<br> '''Automatische Ermittlung des ZATs'''<br> '''Hidden-Optionen und Datenspeicher'''<br> '''Geburtstage und dezimales Alter'''<br> '''Erweiterte Optionen auch auf der Seite'''<br> '''Zusatzspalten Talent/Quote/Aufw./Geb./Alter'''<br> '''Zusatzspalten Quote/Alter/Pos in der Übersicht'''<br> '''Zusatzspalten Alter ersetzen/Aufwertungen kurz+TOR'''<br> '''Zusatzspalten fix/tr./%H/%N/Prios jetzt und Ende'''<br> '''Interaktive Menü-Optionen'''<br> '''Gemeinsame Code- und Datenbasis'''<br> '''Qualitätsbalken'''<br> '''Markierung der Primärskills bei Einzelwerten und Aufwertungen'''<br> '''Beachtung von Jugendförderung und Doppelpositionen'''<br> '''Warnung vor Ende 18 in letzter Periode und mehr am letzten ZAT'''<br> '''Reguläre Ausdrücke im @include'''<br> '''Neues Design und Seite "Opt. Skill"'''<br> '''Gruppierung nach Jahrgängen U13 bis U18 (per Option)'''<br> '''Warnung vor Ende 18 auch im Managerbüro (per Option)'''


|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
Zeile 48: Zeile 48:
// @name        OS2.jugend
// @name        OS2.jugend
// @namespace    http://os.ongapo.com/
// @namespace    http://os.ongapo.com/
// @version      0.73
// @version      0.70
// @copyright    2013+
// @copyright    2013+
// @author      Sven Loges (SLC) / Andreas Eckes (Strindheim BK)
// @author      Sven Loges (SLC) / Andreas Eckes (Strindheim BK)
Zeile 145: Zeile 145:
                   'AltLabel'  : "Nur Saisons anzeigen",
                   'AltLabel'  : "Nur Saisons anzeigen",
                   'AltHotkey' : 'u',
                   'AltHotkey' : 'u',
                   'FormLabel' : "Jahrg\xE4nge U13 bis U19"
                   'FormLabel' : "Jahrg\xE4nge U13 bis U18"
               },
               },
     'zeigeWarnung' : {    // Auswahl, ob eine Warnung erscheint, wenn Talente gezogen werden sollten
     'zeigeWarnung' : {    // Auswahl, ob eine Warnung in der Uebersicht erscheint, wenn Talente gezogen werden sollten
                   'Name'      : "showWarning",
                   'Name'      : "showWarning",
                   'Type'      : __OPTTYPES.SW,
                   'Type'      : __OPTTYPES.SW,
Zeile 158: Zeile 158:
                   'FormLabel' : "Ziehwarnung"
                   'FormLabel' : "Ziehwarnung"
               },
               },
     'zeigeWarnungMonat' : {  // Auswahl, ob eine Warnung erscheint, wenn zum naechsten Abrechnungs-ZAT Talente gezogen werden sollten
     'zeigeWarnungMonat' : {  // Auswahl, ob eine Warnung in der Uebersicht erscheint, wenn zum naechsten Abrechnungs-ZAT Talente gezogen werden sollten
                   'Name'      : "showWarningMonth",
                   'Name'      : "showWarningMonth",
                   'Type'      : __OPTTYPES.SW,
                   'Type'      : __OPTTYPES.SW,
Zeile 169: Zeile 169:
                   'FormLabel' : "Ziehwarnung Monat"
                   'FormLabel' : "Ziehwarnung Monat"
               },
               },
     'zeigeWarnungHome' : {  // Auswahl, ob eine Meldung im Managerbuero erscheint, wenn Talente gezogen werden sollten
     'zeigeWarnungHome' : {  // Auswahl, ob eine extra Meldung im Managerbuero erscheint, wenn Talente gezogen werden sollten
                   'Name'      : "showWarningHome",
                   'Name'      : "showWarningHome",
                   'Type'      : __OPTTYPES.SW,
                   'Type'      : __OPTTYPES.SW,
Zeile 180: Zeile 180:
                   'FormLabel' : "Ziehwarnung B\xFCro"
                   'FormLabel' : "Ziehwarnung B\xFCro"
               },
               },
     'zeigeWarnungDialog' : {  // Auswahl, ob die Meldung im Managerbuero als Dialog erscheinen soll
     'zeigeWarnungDialog' : {  // Auswahl, ob die extra Meldung im Managerbuero als Dialog erscheinen soll
                   'Name'      : "showWarningDialog",
                   'Name'      : "showWarningDialog",
                   'Type'      : __OPTTYPES.SW,
                   'Type'      : __OPTTYPES.SW,
Zeile 190: Zeile 190:
                   'AltHotkey' : 'z',
                   'AltHotkey' : 'z',
                   'FormLabel' : "Ziehwarnung B\xFCro Dialog"
                   'FormLabel' : "Ziehwarnung B\xFCro Dialog"
              },
    'zeigeWarnungAufstieg' : {  // Auswahl, ob eine Warnung in der Uebersicht erscheint, wenn Talente nach Aufstieg nicht mehr gezogen werden koennen
                  'Name'      : "showWarningAufstieg",
                  'Type'      : __OPTTYPES.SW,
                  'Default'  : true,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Ziehwarnung Aufstieg ein",
                  'Hotkey'    : 'ä',
                  'AltLabel'  : "Ziehwarnung Aufstieg aus",
                  'AltHotkey' : 'ä',
                  'FormLabel' : "Ziehwarnung Aufstieg"
              },
    'zeigeWarnungLegende' : {  // Auswahl, ob eine extra Meldung in Teamuebersicht erscheint, die dort als Legende dient
                  'Name'      : "showWarningLegende",
                  'Type'      : __OPTTYPES.SW,
                  'Default'  : true,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Ziehwarnung Legende ein",
                  'Hotkey'    : 'L',
                  'AltLabel'  : "Ziehwarnung Legende aus",
                  'AltHotkey' : 'L',
                  'FormLabel' : "Ziehwarnung Legende"
               },
               },
     'zeigeBalken' : {    // Spaltenauswahl fuer den Qualitaetsbalken des Talents (true = anzeigen, false = nicht anzeigen)
     'zeigeBalken' : {    // Spaltenauswahl fuer den Qualitaetsbalken des Talents (true = anzeigen, false = nicht anzeigen)
Zeile 585: Zeile 563:
                   'FreeValue' : true,
                   'FreeValue' : true,
                   'SelValue'  : false,
                   'SelValue'  : false,
                   'Choice'    : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 ],
                   'Choice'    : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ],
                   'Default'  : 16,
                   'Default'  : 12,
                   'Action'    : __OPTACTION.NXT,
                   'Action'    : __OPTACTION.NXT,
                   'Label'    : "Saison: $",
                   'Label'    : "Saison: $",
Zeile 735: Zeile 713:
                   'Name'      : "drawCounts",
                   'Name'      : "drawCounts",
                   'Type'      : __OPTTYPES.SD,
                   'Type'      : __OPTTYPES.SD,
                   'Hidden'    : true,
                   'Hidden'    : false,
                   'Serial'    : true,
                   'Serial'    : true,
                   'AutoReset' : false,
                   'AutoReset' : false,
Zeile 746: Zeile 724:
                   'Space'    : 0,
                   'Space'    : 0,
                   'Label'    : "Zu ziehen:"
                   'Label'    : "Zu ziehen:"
              },
    'ziehAnzAufstieg' : { // Datenspeicher fuer Anzahl zu ziehender Jugendspieler bis zur naechsten Abrechnung im Falle eines Aufstiegs
                  'Name'      : "drawCountsAufstieg",
                  'Type'      : __OPTTYPES.MC,
                  'ValType'  : 'Number',
                  'Hidden'    : true,
                  'AutoReset' : false,
                  'Permanent' : true,
                  'FreeValue' : true,
                  'SelValue'  : false,
                  'Choice'    : [ 0, 1, 2, 3, 4, 5 ],
                  'Default'  : 0,
                  'Action'    : __OPTACTION.NXT,
                  'Label'    : "Zu ziehen bei Aufstieg: $",
                  'Hotkey'    : 'z',
                  'FormLabel' : "Zu ziehen bei Aufstieg:|$"
               },
               },
     'zatAges' : {        // Datenspeicher fuer (gebrochene) Alter der Jugendspieler
     'zatAges' : {        // Datenspeicher fuer (gebrochene) Alter der Jugendspieler
Zeile 3.952: Zeile 3.914:
// Optionen mit Daten, die ZAT- und Team-bezogen gemerkt werden...
// Optionen mit Daten, die ZAT- und Team-bezogen gemerkt werden...
__TEAMCLASS.optSelect = {
__TEAMCLASS.optSelect = {
                             'datenZat'       : true,
                             'datenZat'     : true,
                             'oldDatenZat'     : true,
                             'oldDatenZat' : true,
                             'fingerprints'   : true,
                             'fingerprints' : true,
                             'birthdays'       : true,
                             'birthdays'   : true,
                             'tClasses'       : true,
                             'tClasses'     : true,
                             'progresses'     : true,
                             'progresses'   : true,
                             'ziehAnz'         : true,
                             'ziehAnz'     : true,
                            'ziehAnzAufstieg' : true,
                             'zatAges'     : true,
                             'zatAges'         : true,
                             'trainiert'   : true,
                             'trainiert'       : true,
                             'positions'   : true,
                             'positions'       : true,
                             'skills'       : true,
                             'skills'         : true,
                             'foerderung'   : true
                             'foerderung'     : true
                         };
                         };


Zeile 4.047: Zeile 4.008:
     const __GEALTERT = ((__AKTZAT >= 72) ? (getIntFromHTML(playerRows[playerRows.length - offsetLower - 1].cells, colIdx.Age) < 13) : false);
     const __GEALTERT = ((__AKTZAT >= 72) ? (getIntFromHTML(playerRows[playerRows.length - offsetLower - 1].cells, colIdx.Age) < 13) : false);
     const __CURRZAT = (__GEALTERT ? 0 : __AKTZAT);
     const __CURRZAT = (__GEALTERT ? 0 : __AKTZAT);
    const __LGNR = __TEAMCLASS.team.LgNr;
    const __KLASSE = (__LGNR > 1) ? (__LGNR > 3) ? 3 : 2 : 1;
     const __DONATION = getOptValue(optSet.foerderung);
     const __DONATION = getOptValue(optSet.foerderung);
     const __BIRTHDAYS = getOptValue(optSet.birthdays, []);
     const __BIRTHDAYS = getOptValue(optSet.birthdays, []);
Zeile 4.073: Zeile 4.032:
             const __AGE = getIntFromHTML(__CELLS, colIdx.Age);
             const __AGE = getIntFromHTML(__CELLS, colIdx.Age);
             const __ISGOALIE = isGoalieFromHTML(__CELLS, colIdx.Age);
             const __ISGOALIE = isGoalieFromHTML(__CELLS, colIdx.Age);
            const __AKTION = getElementFromHTML(__CELLS, colIdx.Akt);
             const __NEWPLAYER = new PlayerRecord(__LAND, __AGE, __ISGOALIE, __SAISON, __CURRZAT, __DONATION);
             const __NEWPLAYER = new PlayerRecord(__LAND, __AGE, __ISGOALIE, __SAISON, __CURRZAT, __DONATION);


Zeile 4.088: Zeile 4.045:
                 __NEWPLAYER.setZusatz(__ZATAGES[__IDX], __TRAINIERT[__IDX], __POSITIONS[__IDX]);
                 __NEWPLAYER.setZusatz(__ZATAGES[__IDX], __TRAINIERT[__IDX], __POSITIONS[__IDX]);
             }
             }
            __NEWPLAYER.createWarnDraw(__AKTION, __KLASSE);


             __PLAYERS[j++] = __NEWPLAYER;
             __PLAYERS[j++] = __NEWPLAYER;
Zeile 4.156: Zeile 4.111:
// index: Position des Spielers im neuen Array von Spielerdaten
// index: Position des Spielers im neuen Array von Spielerdaten
// catIds: PlayerIdMap zum Finden des Spielers ueber die Spielerdaten
// catIds: PlayerIdMap zum Finden des Spielers ueber die Spielerdaten
// return Original-Index der Daten dieses Spielers im Array von Spielerdaten
// return Original-Index der Daten dieses Spielers im Array von Spielerdaten  
function selectPlayerIndex(player, index, catIds) {
function selectPlayerIndex(player, index, catIds) {
     const __MYCAT = player.getCat();
     const __MYCAT = player.getCat();
Zeile 4.175: Zeile 4.130:
// optSet: Gesetzte Optionen (und Config)
// optSet: Gesetzte Optionen (und Config)
function setPlayerData(players, optSet) {
function setPlayerData(players, optSet) {
     const __ZIEHANZAHL = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
     const __AKTZAT = getOptValue(optSet.aktuellerZat);
    let ziehAnzAufstieg = 0;
    const __ZIEHANZ = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
     const __ZATAGES = [];
     const __ZATAGES = [];
     const __TRAINIERT = [];
     const __TRAINIERT = [];
Zeile 4.183: Zeile 4.138:
     for (let i = 0; i < players.length; i++) {
     for (let i = 0; i < players.length; i++) {
         const __ZUSATZ = players[i].calcZusatz();
         const __ZUSATZ = players[i].calcZusatz();
        const __RESTZAT = players[i].getZatAge(players[i].__TIME.end) - __ZUSATZ.zatAge + __AKTZAT;


         if (__ZUSATZ.zatAge !== undefined) {  // braucht Geburtstag fuer gueltige Werte!
         if (__ZUSATZ.zatAge !== undefined) {  // braucht Geburtstag fuer gueltige Werte!
             const __INDEX = players[i].calcZiehIndex();  // Lfd. Nummer des Abrechnungsmonats (0-basiert)
             const __INDEX = parseInt(__RESTZAT / 6 + 1) - 1;  // Lfd. Nummer des Abrechnungsmonats (0-basiert)


             if ((__INDEX >= 0) && (__INDEX < __ZIEHANZAHL.length)) {
             if ((__INDEX >= 0) && (__INDEX < __ZIEHANZ.length)) {
                 __ZIEHANZAHL[__INDEX]++;
                 __ZIEHANZ[__INDEX]++;
             }
             }


             __ZATAGES[i] = __ZUSATZ.zatAge;
             __ZATAGES[i] = __ZUSATZ.zatAge;
        }
        if (players[i].isZiehAufstieg()) {
            ziehAnzAufstieg++;
         }
         }
         __TRAINIERT[i] = __ZUSATZ.trainiert;
         __TRAINIERT[i] = __ZUSATZ.trainiert;
Zeile 4.200: Zeile 4.153:
     }
     }


     setOpt(optSet.ziehAnz, __ZIEHANZAHL, false);
     setOpt(optSet.ziehAnz, __ZIEHANZ, false);
    setOpt(optSet.ziehAnzAufstieg, ziehAnzAufstieg, false);
     setOpt(optSet.zatAges, __ZATAGES, false);
     setOpt(optSet.zatAges, __ZATAGES, false);
     setOpt(optSet.trainiert, __TRAINIERT, false);
     setOpt(optSet.trainiert, __TRAINIERT, false);
Zeile 4.332: Zeile 4.284:
     this.warnHome = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnungHome, __SHOWALL) && getOptValue(optSet.zeigeWarnungHome));
     this.warnHome = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnungHome, __SHOWALL) && getOptValue(optSet.zeigeWarnungHome));
     this.warnDialog = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnungDialog, __SHOWALL) && getOptValue(optSet.zeigeWarnungDialog));
     this.warnDialog = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnungDialog, __SHOWALL) && getOptValue(optSet.zeigeWarnungDialog));
    this.warnAufstieg = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnungAufstieg, __SHOWALL) && getOptValue(optSet.zeigeWarnungAufstieg));
    this.warnLegende = (__ZATAGES && getValue(__SHOWCOL.zeigeWarnungLegende, __SHOWALL) && getOptValue(optSet.zeigeWarnungLegende));
     this.bar = (__PROJECTION && getValue(__SHOWCOL.zeigeBalken, __SHOWALL) && getOptValue(optSet.zeigeBalken));
     this.bar = (__PROJECTION && getValue(__SHOWCOL.zeigeBalken, __SHOWALL) && getOptValue(optSet.zeigeBalken));
     this.barAbs = getOptValue(optSet.absBalken);
     this.barAbs = getOptValue(optSet.absBalken);
Zeile 4.515: Zeile 4.465:
                           },  // Ende addTitles()
                           },  // Ende addTitles()
         'addValues'      : function(player, playerRow, color = "#FFFFFF") {
         'addValues'      : function(player, playerRow, color = "#FFFFFF") {
                              // Warnlevel des Spielers anpassen...
                              const __WARNDRAW = player.warnDraw || player.warnDrawAufstieg || __NOWARNDRAW;
                              __WARNDRAW.setWarn(this.warn, this.warnMonth, this.warnAufstieg);
                               const __IDXPRI = getIdxPriSkills(player.getPos());
                               const __IDXPRI = getIdxPriSkills(player.getPos());
                               const __COLOR = __WARNDRAW.getColor(player.isGoalie ? getColor('TOR') : color); // Angepasst an Ziehwarnung
                              const __COLALERT = getColor('STU');  // rot
                              const __MUSTDRAW = ((this.warn || this.warnMonth) && (player.zatLeft < 1));
                               const __COLOR = (__MUSTDRAW ? __COLALERT : player.isGoalie ? getColor('TOR') : color);
                               const __POS1COLOR = getColor((player.getPosPercent() > 99.99) ? 'LEI' : player.getPos());
                               const __POS1COLOR = getColor((player.getPosPercent() > 99.99) ? 'LEI' : player.getPos());
                               const __OSBLAU = getColor("");
                               const __OSBLAU = getColor("");
Zeile 4.560: Zeile 4.508:
                                   this.addAndFillCell(playerRow, player.getAge(), __COLOR, null, 2);
                                   this.addAndFillCell(playerRow, player.getAge(), __COLOR, null, 2);
                               }
                               }
                               if (__WARNDRAW.monthDraw()) {  // Abrechnungszeitraum vor dem letztmoeglichen Ziehen...
                               if (__MUSTDRAW || (this.warnMonth && (player.zatLeft < 6))) {  // Abrechnungszeitraum vor dem letztmoeglichen Ziehen...
                                   formatCell(playerRow.cells[this.colIdx.Age], true, __WARNDRAW.colAlert, null, 1.0);
                                   formatCell(playerRow.cells[this.colIdx.Age], true, __COLALERT, null, 1.0);
                               }
                               }
                               if (this.fix) {
                               if (this.fix) {
Zeile 4.723: Zeile 4.671:
     // this.trainiert: Anzahl der erfolgreichen Trainingspunkte
     // this.trainiert: Anzahl der erfolgreichen Trainingspunkte
     // indirekt this.zatAge und this.bestPos
     // indirekt this.zatAge und this.bestPos
    // in this.createWarnDraw() definiert:
    // this.warnDraw: Behandlung von Warnungen Ende 18
    // this.warnDrawAufstieg: Behandlung von Warnungen bei Aufstieg


     // in this.getPos() definiert:
     // in this.getPos() definiert:
Zeile 4.781: Zeile 4.725:
                                       }
                                       }
                                   },  // Ende this.initPlayer()
                                   },  // Ende this.initPlayer()
        'createWarnDraw'        : function(ziehmich = null, klasse = 1) {  // ziehmich: input Element zum Ziehen; klasse: Spielklasse 1, 2, 3
                                      // Objekte fuer die Verwaltung der Ziehwarnungen...
                                      this.warnDraw = undefined;
                                      this.warnDrawAufstieg = undefined;
                                      if (ziehmich) {
                                          const __LASTZAT = this.currZAT + this.getZatLeft();
                                          if (__LASTZAT < 72) {  // U19
                                              this.warnDraw = new WarnDrawPlayer(this, getColor('STU'));  // rot
                                              __LOG[4](this.getAge().toFixed(2), "rot");
                                          } else if (__LASTZAT < Math.max(2, klasse) * 72) {  // Rest bis inkl. U18 (Liga 1 und 2) bzw. U17 (Liga 3)
                                              // do nothing
                                          } else if (__LASTZAT < (klasse + 1) * 72) {  // U17/U16 je nach Liga 2/3
                                              this.warnDrawAufstieg = new WarnDrawPlayer(this, getColor('OMI'));  // magenta
                                              this.warnDrawAufstieg.setAufstieg();
                                              __LOG[4](this.getAge().toFixed(2), "magenta");
                                          }
                                      }
                                  },  // Ende this.createWarnDraw()
         'setSkills'            : function(skills) {
         'setSkills'            : function(skills) {
                                       // Berechnet die Opti-Werte, sortiert das Positionsfeld und berechnet die Einzelskills mit Ende 18
                                       // Berechnet die Opti-Werte, sortiert das Positionsfeld und berechnet die Einzelskills mit Ende 18
Zeile 4.887: Zeile 4.812:
                                       if (when === this.__TIME.end) {
                                       if (when === this.__TIME.end) {
                                           return (18 - 12) * 72 - 1;  // (max.) Trainings-ZATs bis Ende 18
                                           return (18 - 12) * 72 - 1;  // (max.) Trainings-ZATs bis Ende 18
                                       } else if (this.zatAge !== undefined) {
                                       } else {
                                           return this.zatAge;
                                           return this.zatAge;
                                      } else {
                                          __LOG[4]("Empty getZatAge()");
                                          return NaN;
                                       }
                                       }
                                   },
                                   },
Zeile 4.904: Zeile 4.825:


                                       return this.zatLeft;
                                       return this.zatLeft;
                                  },
        'calcZiehIndex'        : function() {
                                      //const __RESTZAT = this.getZatAge(this.__TIME.end) - this.getZatAge() + this.currZAT;
                                      //const __INDEX = parseInt(__RESTZAT / 6 + 1) - 1;  // Lfd. Nummer des Abrechnungsmonats (0-basiert)
                                      return (this.warnDraw && this.warnDraw.calcZiehIndex(this.currZAT));
                                  },
        'isZiehAufstieg'        : function() {
                                      return (this.warnDrawAufstieg && this.warnDrawAufstieg.isZiehAufstieg());
                                   },
                                   },
         'getAge'                : function(when = this.__TIME.now) {
         'getAge'                : function(when = this.__TIME.now) {
Zeile 5.130: Zeile 5.042:
     });
     });


// Klasse WarnDrawPlayer *****************************************************************
// Funktionen fuer die HTML-Seite *******************************************************


function WarnDrawPlayer(player, alertColor) {
// Liest eine Zahl aus der Spalte einer Zeile der Tabelle aus (z.B. Alter, Geburtsdatum)
     'use strict';
// cells: Die Zellen einer Zeile
// colIdxInt: Spaltenindex der gesuchten Werte
// return Spalteneintrag als Zahl (-1 fuer "keine Zahl", undefined fuer "nicht gefunden")
function getIntFromHTML(cells, colIdxInt) {
     const __CELL = getValue(cells[colIdxInt], { });
    const __TEXT = __CELL.textContent;


     this.player = player;
     if (__TEXT !== undefined) {
        try {
            const __VALUE = parseInt(__TEXT, 10);


    if (this.player !== undefined) {
            if (! isNaN(__VALUE)) {
        // Default Warnlevel...
                return __VALUE;
        this.setZatLeft(player.getZatLeft());
            }
        this.currZAT = player.currZAT;
         } catch (ex) { }
        this.setWarn(true, true, true);
 
         this.colAlert = alertColor || this.alertColor();
         return -1;
    } else {
        // Kein Warnlevel...
        this.setZatLeft(undefined);
        this.currZAT = undefined;
        this.setWarn(false, false, false);
         this.colAlert = undefined;
     }
     }
    return undefined;
}
}


Class.define(WarnDrawPlayer, Object, {
// Liest eine Dezimalzahl aus der Spalte einer Zeile der Tabelle aus
        '__MONATEBISABR'    : 1,
// cells: Die Zellen einer Zeile
        '__ZATWARNVORLAUF'  : 1,
// colIdxInt: Spaltenindex der gesuchten Werte
        '__ZATMONATVORLAUF' : 6,
// return Spalteneintrag als Dezimalzahl (undefined fuer "keine Zahl" oder "nicht gefunden")
        'setZatLeft'        : function(zatLeft) {
function getFloatFromHTML(cells, colIdxFloat) {
                                  this.zatLeft = zatLeft;
    const __CELL = getValue(cells[colIdxFloat], { });
                              },
     const __TEXT = __CELL.textContent;
        'setWarn'          : function(warn, warnMonth, warnAufstieg) {
                                  this.warn = (this.aufstieg ? warnAufstieg : warn);
                                  this.warnMonth = warnMonth;
                              },
        'alertColor'        : function() {
                                  return getColor('STU');  // rot
                              },
        'getColor'          : function(color) {
                                  return ((this.mustDraw() && this.colAlert) ? this.colAlert : color);
                              },
        'calcZiehIndex'     : function(currZAT) {
                                  const __RESTZAT = this.zatLeft + currZAT;
                                  const __INDEX = parseInt(__RESTZAT / 6 + 1) - this.__MONATEBISABR; // Lfd. Nummer des Abrechnungsmonats (0-basiert)


                                  return __INDEX;
    if (__TEXT !== undefined) {
                              },
         try {
         'isZiehAufstieg'    : function() {
            return parseFloat(__TEXT);
                                  return this.aufstieg;
        } catch (ex) { }
                              },
    }
        'setAufstieg'      : function() {
                                  this.aufstieg = true;


                                  if (this.isZiehAufstieg()) {
    return undefined;
                                      this.setZatLeft(72 - this.currZAT - this.__ZATWARNVORLAUF);
}
                                  }


                                  return this.zatLeft;
// Liest einen String aus der Spalte einer Zeile der Tabelle aus
                              },
// cells: Die Zellen einer Zeile
        'mustDraw'          : function() {
// colIdxStr: Spaltenindex der gesuchten Werte
                                  return ((this.warn || this.warnMonth) && (this.zatLeft < this.__ZATWARNVORLAUF));
// return Spalteneintrag als String ("" fuer "nicht gefunden")
                              },
function getStringFromHTML(cells, colIdxStr) {
        'monthDraw'        : function() {
    const __CELL = getValue(cells[colIdxStr], { });
                                  return (this.mustDraw() || (this.warn && (this.aufstieg || this.warnMonth) && (this.zatLeft < this.__ZATMONATVORLAUF))); // Abrechnungszeitraum vor dem letztmoeglichen Ziehen...
     const __TEXT = __CELL.textContent;
                              }
     });


const __NOWARNDRAW = new WarnDrawPlayer(undefined, undefined); // inaktives Objekt
    return getValue(__TEXT.toString(), "");
}


// Klasse WarnDrawMessage *****************************************************************
// Liest die Talentklasse ("wenig", "normal", "hoch") aus der Spalte einer Zeile der Tabelle aus
// cells: Die Zellen einer Zeile
// colIdxStr: Spaltenindex der gesuchten Werte
// return Talent als Zahl (-1=wenig, 0=normal, +1=hoch)
function getTalentFromHTML(cells, colIdxTal) {
    const __TEXT = getStringFromHTML(cells, colIdxTal);


function WarnDrawMessage(optSet, currZAT) {
    return parseInt((__TEXT === 'wenig') ? -1 : (__TEXT === 'hoch') ? +1 : 0, 10);
    'use strict';
}


     this.optSet = optSet;
// Liest die Einzelskills aus der Spalte einer Zeile der Tabelle aus
// cells: Die Zellen einer Zeile
// colIdx: Liste von Spaltenindices der gesuchten Werte mit den Eintraegen
// 'Einz' (erste Spalte) und 'Zus' (Spalte hinter dem letzten Eintrag)
// return Skills als Array von Zahlen
function getSkillsFromHTML(cells, colIdx) {
     const __RESULT = [];


     this.warn = getOptValue(this.optSet.zeigeWarnung, true);
     for (let i = colIdx.Einz; i < colIdx.Zus; i++) {
    this.warnMonth = getOptValue(this.optSet.zeigeWarnungMonat, true);
        __RESULT[i - colIdx.Einz] = getIntFromHTML(cells, i);
    this.warnHome = getOptValue(this.optSet.zeigeWarnungHome, true);
     }
    this.warnDialog = getOptValue(this.optSet.zeigeWarnungDialog, false);
    this.warnAufstieg = getOptValue(this.optSet.zeigeWarnungAufstieg, true);
     this.warnLegende = getOptValue(this.optSet.zeigeWarnungLegende, true);


     this.out = {
     return __RESULT;
                  'supertag' : true,
}
                  'top'      : true,
                  'link'    : true,
                  'label'    : true,
                  'bottom'  : true
              };


    this.setOptionHome();
// Liest aus, ob der Spieler Torwart oder Feldspieler ist
 
// cells: Die Zellen einer Zeile
     this.startMessage(currZAT);
// colIdxClass: Spaltenindex einer fuer TOR eingefaerbten Zelle
// return Angabe, der Spieler Torwart oder Feldspieler ist
function isGoalieFromHTML(cells, colIdxClass) {
     return (cells[colIdxClass].className === 'TOR');
}
}


Class.define(WarnDrawMessage, Object, {
// Liest einen String aus der Spalte einer Zeile der Tabelle aus, nachdem dieser konvertiert wurde
        '__ZATWARNVORLAUF'  : 1,
// cells: Die Zellen einer Zeile
        '__ZATMONATVORLAUF' : 6,
// colIdxStr: Spaltenindex der gesuchten Werte
        'startMessage'      : function(currZAT) {
// convertFun: Funktion, die den Wert konvertiert
                                  this.setZat(currZAT);
// return Spalteneintrag als String ("" fuer "nicht gefunden")
                                  this.createMessage();
function convertStringFromHTML(cells, colIdxStr, convertFun = sameValue) {
                              },
    const __CELL = getValue(cells[colIdxStr], { });
        'setZat'            : function(currZAT) {
    const __TEXT = convertFun(__CELL.textContent, __CELL, colIdxStr, 0);
                                  this.currZAT = currZAT;


                                  if (currZAT === undefined) {
    if (__TEXT !== undefined) {
                                      this.abrZAT = undefined;
        __CELL.innerHTML = __TEXT;
                                      this.rest  = undefined;
     }
                                      this.anzahl = undefined;
                                  } else {
                                      this.configureZat();
                                  }
                              },
        'setOptionHome'     : function() {
                                  this.warnOption = this.hasHome();
                              },
        'setOptionLegende'  : function() {
                                  this.warnOption = this.hasLegende();
                              },
        'configureZat'      : function() {
                                  const __ZIEHANZAHL = getOptValue(this.optSet.ziehAnz, []);
                                  const __INDEX = parseInt(this.currZAT / 6);


                                  this.abrZAT = (__INDEX + 1) * 6;
    return getValue(__TEXT.toString(), "");
                                  this.rest  = 5 - (this.currZAT % 6);
}
                                  this.anzahl = __ZIEHANZAHL[__INDEX];
                              },
        'getTextMessage'    : function() {
                                  return "ZAT " + this.abrZAT + ' ' + ((this.anzahl > 1) ? "m\xFCssen " + this.anzahl : "muss einer") +
                                        " deiner Jugendspieler in das Profiteam \xFCbernommen werden, ansonsten verschwinde" + ((this.anzahl > 1) ? "n sie" : "t er") + '!';
                              },
        'createMessage'    : function() {
                                  this.label = undefined;
                                  this.when = undefined;
                                  this.text = undefined;


                                  if (this.hasHome() || this.hasLegende() || this.hasDialog()) {
// Liest ein Array von String-Werten aus den Spalten ab einer Zeile der Tabelle aus, nachdem diese konvertiert wurden
                                      if (this.anzahl > 0) {
// cells: Die Zellen einer Zeile
                                          this.text = this.getTextMessage();
// colIdxArr: Erster Spaltenindex der gesuchten Werte
// arrOrLength: Entweder ein Datenarray zum Fuellen oder die Anzahl der zu lesenden Werte
// convertFun: Funktion, die die Werte konvertiert
// return Array mit Spalteneintraegen als String ("" fuer "nicht gefunden")
function convertArrayFromHTML(cells, colIdxArr, arrOrLength = 1, convertFun = sameValue) {
    const __ARR = ((typeof arrOrLength === 'number') ? { } : arrOrLength);
    const __LENGTH = getValue(__ARR.length, arrOrLength);
    const __RET = [];


                                          if (this.warnMonth && (this.rest > 0)) {
    for (let index = 0, colIdx = colIdxArr; index < __LENGTH; index++, colIdx++) {
                                              this.label = "Warnung";
         const __CELL = getValue(cells[colIdx], { });
                                              this.when = "Bis zur n\xE4chsten Abrechnung am ";
         const __TEXT = convertFun(getValue(__ARR[index], __CELL.textContent), __CELL, colIdx, index);
                                          } else if ((this.warn || this.warnMonth) && (this.rest === 0)) {
 
                                              this.label = "LETZTE WARNUNG VOR DER ABRECHNUNG";
         if (__TEXT !== undefined) {
                                              this.when = "Bis zum n\xE4chsten ";
            __CELL.innerHTML = __TEXT;
                                          }
        }
                                      }
                                  }
                              },
        'hasMessage'        : function() {
                                  return !! this.when;
                              },
         'hasHome'          : function() {
                                  return this.warnHome;
                              },
        'hasLegende'        : function() {
                                  return this.warnLegende;
                              },
         'hasOption'        : function() {
                                  return this.warnOption;
                              },
        'hasDialog'        : function() {
                                  return this.warnDialog;
                              },
         'showMessage'      : function(anchor, tag, appendFind = true) { // appendFind: true = append, false = insertBefore, "..." search string = insert at find position
                                  let ret = (anchor || { }).innerHTML;


                                  if (this.hasMessage()) {
        __RET.push(getValue(__TEXT, "").toString());
                                      if (this.hasOption()) {
    }
                                          const __OLDHTML = ret;
                                          const __HTML = this.getHTML(tag);


                                          if ((typeof appendFind) === 'string') {
    return __RET;
                                              const __INDEX = __OLDHTML.indexOf(appendFind);
}
                                              const __POS = (~ __INDEX) ? __INDEX : __OLDHTML.length;


                                              ret = __OLDHTML.substring(0, __POS) + __HTML + __OLDHTML.substring(__POS);
// Konvertiert den Aufwertungstext einer Zelle auf der Jugend-Teamuebersicht
                                          } else if (appendFind) {
// value: Der Inhalt dieser Zeile ("+1 SKI +1 OPT" bzw. "+2 SKI)
                                              ret = __OLDHTML + __HTML;
// cell: Zelle, in der der Text stand (optional)
                                          } else {
// return Der konvertierte String ("SKI OPT" bzw. "SKI SKI")
                                              ret = __HTML + __OLDHTML;
function convertAufwertung(value, cell = undefined) {
                                          }
    if (value !== undefined) {
        value = value.replace(/\+2 (\w+)/, "$1 $1").replace(/\+1 /g, "");


                                          anchor.innerHTML = ret;
        if (cell) {
                                      }
            if (cell.className === 'TOR') {
                                  }
                value = convertGoalieSkill(value);
            }


                                  return ret;
            cell.align = 'left';
                              },
         }
        'showDialog'        : function(dlgFun) {
     }
                                  if (this.hasMessage()) {
                                      if (this.hasDialog() && (this.rest === 0)) {
                                          dlgFun(this.label, this.when + this.text);
                                      }
                                  }
                              },
        'tagText'          : function(tag, text) {
                                  return ((tag !== undefined) ? this.getOpeningTag(tag) + text + this.getClosingTag(tag) : text);
                              },
        'tagParagraph'      : function(tag, text) {
                                  return this.tagText(tag, this.tagText(this.getSubTag(tag), text));
                              },
        'getSubTag'        : function(tag) {
                                  return ((tag === 'tr') ? 'td' + this.getColorTD() : ((tag === 'p') ? this.getColorTag() : undefined));
                              },
         'getSuperTag'      : function(tag) {
                                  return ((tag === 'p') ? 'div' : undefined);
                              },
        'getOpeningTag'     : function(tag) {
                                  return '<' + tag + '>';
                              },
        'getClosingTag'    : function(tag) {
                                  const __INDEX1 = (tag ? tag.indexOf(' ') : -1);
                                  const __INDEX2 = (tag ? tag.indexOf('=') : -1);
                                  const __INDEX = ((~ __INDEX1) && (~ __INDEX2)) ? Math.min(__INDEX1, __INDEX2) : Math.max(__INDEX1, __INDEX2);
                                  const __TAGNAME = ((~ __INDEX) ? tag.substring(0, __INDEX) : tag);


                                  return "</" + __TAGNAME + '>';
     return value;
                              },
}
        'getLink'          : function() {
                                  return './ju.php';
                              },
        'getTopHTML'        : function(tag) {
                                  return this.tagParagraph(tag, "&nbsp;");
                              },
        'getBottomHTML'     : function(tag) {
                                  return this.tagParagraph(tag, "&nbsp;");
                              },
        'getColorTag'      : function() {
                                  return "color='red'";  // rot
                              },
        'getColorTD'        : function() {
                                  return " class='STU'";  // rot
                              },
        'getHTML'          : function(tag = 'p') {
                                  return this.tagParagraph((this.out.supertag ? this.getSuperTag(tag) : undefined), (this.out.top ? this.getTopHTML(tag) : "") +
                                        this.tagParagraph(tag, this.tagText('b', this.tagText((this.out.link ? "a href='" + this.getLink() + "'" : undefined),
                                        (this.out.label ? this.label + ": " : "") + this.when + this.text))) + (this.out.bottom ? this.getBottomHTML(tag) : ""));
                              }
    });


Object.defineProperty(WarnDrawMessage.prototype, 'innerHTML', {
// Konvertiert die allgemeinen Skills in die eines Torwarts
        get : function() {
// value: Ein Text, der die Skillnamen enthaelt
                  return this.getHTML('p');
// return Der konvertierte String mit Aenderungen (z.B. "FAN" statt "KOB") oder unveraendert
              }
function convertGoalieSkill(value) {
     });
    if (value !== undefined) {
        value = value.replace(/\w+/g, getGoalieSkill);
     }


// Klasse WarnDrawMessageAufstieg *****************************************************************
    return value;
}


function WarnDrawMessageAufstieg(optSet, currZAT) {
// Konvertiert einen Aufwertungstext fuer einen Skillnamen in den fuer einen Torwart
     'use strict';
// name: Allgemeiner Skillname (abgeleitet von den Feldspielern)
// return Der konvertierte String (z.B. "FAN" statt "KOB") oder unveraendert
function getGoalieSkill(name) {
     const __GOALIESKILLS = {
                              'SCH' : 'ABS',
                              'BAK' : 'STS',
                              'KOB' : 'FAN',
                              'ZWK' : 'STB',
                              'DEC' : 'SPL',
                              'GES' : 'REF'
                          };


     WarnDrawMessage.call(this, optSet, currZAT);
     return getValue(__GOALIESKILLS[name], name);
}


    this.out.top = false// kein Vorschub vor der Zeile
// Liest die Aufwertungen eines Spielers aus und konvertiert je nachdem, ob der Spieler Torwart oder Feldspieler ist
// cells: Die Zellen einer Zeile
// colIdxAuf: Spaltenindex der gesuchten Aufwertungen
// shortForm: true = abgekuerzt, false = Originalform
// return Konvertierte Aufwertungen (kurze oder lange Form, aber in jedem Fall fuer Torwart konvertiert)
function getAufwertFromHTML(cells, colIdxAuf, shortForm = true) {
    const __ISGOALIE = isGoalieFromHTML(cells, colIdxAuf);


     this.warn = (this.warn && this.warnAufstieg);  // kann man ausschalten
     return convertStringFromHTML(cells, colIdxAuf, (shortForm ? convertAufwertung : __ISGOALIE ? convertGoalieSkill : undefined));
    this.startMessage(currZAT); // 2. Aufruf (zur Korrektur)
}
}


Class.define(WarnDrawMessageAufstieg, WarnDrawMessage, {
// Identitaetsfunktion. Konvertiert nichts, sondern liefert einfach den Wert zurueck
        'configureZat'      : function() {
// value: Der uebergebene Wert
                                  const __ZIEHANZAUFSTIEG = getOptValue(this.optSet.ziehAnzAufstieg, 0);
// return Derselbe Wert
                                  const __INDEX = parseInt(this.currZAT / 6);
function sameValue(value) {
    return value;
}


                                  this.abrZAT = (__INDEX + 1) * 6;
// Existenzfunktion. Liefert zurueck, ob ein Wert belegt ist
                                  this.rest  = 5 - (this.currZAT % 6);
// value: Der uebergebene Wert
                                  this.anzahl = ((this.currZAT + this.__ZATMONATVORLAUF > 72 - this.__ZATWARNVORLAUF) ? __ZIEHANZAUFSTIEG : 0);
// return Angabe ob Wert belegt ist
 
function existValue(value) {
                                  this.warnDialog = false;    // kein Dialog fuer Aufstiegswarnung
    return !! value;
                                  this.warnMonth = this.warn;  // nur im letzten Monat der Saison!
}
                              },
        'getTextMessage'    : function() {
                                  return "ZAT " + this.abrZAT + " ist im Falle eines Aufstiegs f\xFCr " + ((this.anzahl > 1) ? "" + this.anzahl : "einen") +
                                        " deiner Jugendspieler m\xF6glicherweise die letzte Chance, " + ((this.anzahl > 1) ? " diese noch vor ihrem" : "ihn noch vor seinem") +
                                        " Geburtstag in der n\xE4chsten Saison in das Profiteam zu \xFCbernehmen!";
                              },
        'getColorTag'      : function() {
                                  return "color='magenta'";  // magenta
                              },
        'getColorTD'        : function() {
                                  return " class='OMI'"; // magenta
                              }
    });


// Ende Hilfs-Klassen *****************************************************************
// Liefert den ganzzeiligen Anteil einer Zahl zurueck, indem alles hinter einem Punkt abgeschnitten wird
// value: Eine uebergebene Dezimalzahl
// return Der ganzzeilige Anteil dieser Zahl
function floorValue(value, dot = '.') {
    if ((value === 0) || (value && isFinite(value))) {
        const __VALUE = value.toString();
        const __INDEXDOT = (__VALUE ? __VALUE.indexOf(dot) : -1);


// Funktionen fuer die HTML-Seite *******************************************************
        return Number((~ __INDEXDOT) ? __VALUE.substring(0, __INDEXDOT) : __VALUE);
 
    } else {
// Liest eine Zahl aus der Spalte einer Zeile der Tabelle aus (z.B. Alter, Geburtsdatum)
         return value;
// cells: Die Zellen einer Zeile
// colIdxInt: Spaltenindex der gesuchten Werte
// return Spalteneintrag als Zahl (-1 fuer "keine Zahl", undefined fuer "nicht gefunden")
function getIntFromHTML(cells, colIdxInt) {
    const __CELL = getValue(cells[colIdxInt], { });
    const __TEXT = __CELL.textContent;
 
    if (__TEXT !== undefined) {
        try {
            const __VALUE = parseInt(__TEXT, 10);
 
            if (! isNaN(__VALUE)) {
                return __VALUE;
            }
        } catch (ex) { }
 
         return -1;
     }
     }
    return undefined;
}
}


// Liest eine Dezimalzahl aus der Spalte einer Zeile der Tabelle aus
// Liefert einen rechtsbuendigen Text zurueck, der links aufgefuellt wird
// cells: Die Zellen einer Zeile
// value: Ein uebergebener Wert
// colIdxInt: Spaltenindex der gesuchten Werte
// size: Zielbreite (clipping fuer < 0: Abschneiden, falls zu lang)
// return Spalteneintrag als Dezimalzahl (undefined fuer "keine Zahl" oder "nicht gefunden")
// char: Zeichen zum Auffuellen
function getFloatFromHTML(cells, colIdxFloat) {
// return Ein String, der mindestens |size| lang ist (oder genau, falls size < 0, also clipping)
     const __CELL = getValue(cells[colIdxFloat], { });
function padLeft(value, size = 4, char = ' ') {
     const __TEXT = __CELL.textContent;
     const __SIZE = Math.abs(size);
    const __CLIP = (size < 0);
     const __VALUE = (value ? value.toString() : "");
    let i = __VALUE.length;
    let str = "";


     if (__TEXT !== undefined) {
     while (i < __SIZE) {
         try {
         str += char;
            return parseFloat(__TEXT);
         i += char.length;
         } catch (ex) { }
     }
     }
    str = ((i > __SIZE) ? str.slice(0, __SIZE - __VALUE.length - 1) : str) + __VALUE;


     return undefined;
     return (__CLIP ? str.slice(size) : str);
}
}


// Liest einen String aus der Spalte einer Zeile der Tabelle aus
// Liefert eine rechtsbuendigen Zahl zurueck, der links (mit Nullen) aufgefuellt wird
// cells: Die Zellen einer Zeile
// value: Eine uebergebene Zahl
// colIdxStr: Spaltenindex der gesuchten Werte
// size: Zielbreite (Default: 2)
// return Spalteneintrag als String ("" fuer "nicht gefunden")
// char: Zeichen zum Auffuellen (Default: '0')
function getStringFromHTML(cells, colIdxStr) {
// forceClip: Abschneiden erzwingen, falls zu lang?
     const __CELL = getValue(cells[colIdxStr], { });
// return Eine Zahl als String, der mindestens 'size' lang ist (oder genau, falls size < 0, also clipping)
     const __TEXT = __CELL.textContent;
function padNumber(value, size = 2, char = '0') {
 
     if ((value === 0) || (value && isFinite(value))) {
     return getValue(__TEXT.toString(), "");
        return padLeft(value, size, char);
     } else {
        return value;
     }
}
}


// Liest ein erstes Element aus der Spalte einer Zeile der Tabelle aus
// Hilfsfunktionen **********************************************************************
// cells: Die Zellen einer Zeile
// colIdxStr: Spaltenindex der gesuchten Werte
// return Spalteneintrag als Element (null fuer "nicht gefunden")
function getElementFromHTML(cells, colIdxStr) {
    const __CELL = getValue(cells[colIdxStr], { });


     return __CELL.firstElementChild;
// Sortiert das Positionsfeld per BubbleSort
}
function sortPositionArray(array) {
    const __TEMP = [];
     let transposed = true;
    // TOR soll immer die letzte Position im Feld sein, deshalb - 1
    let length = array.length - 1;


// Liest die Talentklasse ("wenig", "normal", "hoch") aus der Spalte einer Zeile der Tabelle aus
    while (transposed && (length > 1)) {
// cells: Die Zellen einer Zeile
        transposed = false;
// colIdxStr: Spaltenindex der gesuchten Werte
        for (let i = 0; i < length - 1; i++) {
// return Talent als Zahl (-1=wenig, 0=normal, +1=hoch)
            // Vergleich Opti-Werte:
function getTalentFromHTML(cells, colIdxTal) {
            if (array[i][1] < array[i + 1][1]) {
    const __TEXT = getStringFromHTML(cells, colIdxTal);
                // vertauschen
 
                __TEMP[0] = array[i][0];
    return parseInt((__TEXT === 'wenig') ? -1 : (__TEXT === 'hoch') ? +1 : 0, 10);
                __TEMP[1] = array[i][1];
                array[i][0] = array[i + 1][0];
                array[i][1] = array[i + 1][1];
                array[i + 1][0] = __TEMP[0];
                array[i + 1][1] = __TEMP[1];
                transposed = true;
            }
        }
        length--;
    }
}
}


// Liest die Einzelskills aus der Spalte einer Zeile der Tabelle aus
// Schaut nach, ob der uebergebene Index zu einem trainierbaren Skill gehoert
// cells: Die Zellen einer Zeile
// Die Indizes gehen von 0 (SCH) bis 16 (EIN)
// colIdx: Liste von Spaltenindices der gesuchten Werte mit den Eintraegen
function isTrainableSkill(idx) {
// 'Einz' (erste Spalte) und 'Zus' (Spalte hinter dem letzten Eintrag)
     const __TRAINABLESKILLS = getIdxTrainableSkills();
// return Skills als Array von Zahlen
    const __IDX = parseInt(idx, 10);
function getSkillsFromHTML(cells, colIdx) {
    let result = false;
     const __RESULT = [];


     for (let i = colIdx.Einz; i < colIdx.Zus; i++) {
     for (let idxTrainable of __TRAINABLESKILLS) {
         __RESULT[i - colIdx.Einz] = getIntFromHTML(cells, i);
         if (__IDX === idxTrainable) {
            result = true;
            break;
        }
     }
     }


     return __RESULT;
     return result;
}
}


// Liest aus, ob der Spieler Torwart oder Feldspieler ist
// Gibt alle Skill-Namen zurueck
// cells: Die Zellen einer Zeile
function getAllSkillNames(isGoalie = false) {
// colIdxClass: Spaltenindex einer fuer TOR eingefaerbten Zelle
    if (isGoalie) {
// return Angabe, der Spieler Torwart oder Feldspieler ist
        return [ 'ABS', 'STS', 'FAN', 'STB', 'SPL', 'REF', 'FUQ', 'ERF', 'AGG', 'PAS', 'AUS', 'UEB', 'WID', 'SEL', 'DIS', 'ZUV', 'EIN' ];
function isGoalieFromHTML(cells, colIdxClass) {
    } else {
    return (cells[colIdxClass].className === 'TOR');
        return [ 'SCH', 'BAK', 'KOB', 'ZWK', 'DEC', 'GES', 'FUQ', 'ERF', 'AGG', 'PAS', 'AUS', 'UEB', 'WID', 'SEL', 'DIS', 'ZUV', 'EIN' ];
    }
}
}


// Liest einen String aus der Spalte einer Zeile der Tabelle aus, nachdem dieser konvertiert wurde
// Gibt den Skill-Namen zu einem Index zurueck
// cells: Die Zellen einer Zeile
function getSkillName(idx, isGoalie = false) {
// colIdxStr: Spaltenindex der gesuchten Werte
     const __ALLNAMES = getAllSkillNames(isGoalie);
// convertFun: Funktion, die den Wert konvertiert
// return Spalteneintrag als String ("" fuer "nicht gefunden")
function convertStringFromHTML(cells, colIdxStr, convertFun = sameValue) {
     const __CELL = getValue(cells[colIdxStr], { });
    const __TEXT = convertFun(__CELL.textContent, __CELL, colIdxStr, 0);


     if (__TEXT !== undefined) {
     return __ALLNAMES[idx];
        __CELL.innerHTML = __TEXT;
}
    }


     return getValue(__TEXT.toString(), "");
// Gibt den Skill-Namen zu einem Index-Array zurueck
function getSkillNameArray(idxArr, isGoalie = false) {
     return (idxArr ? idxArr.map(function(item) {
                                    return getSkillName(item, isGoalie);
                                }) : idxArr);
}
}


// Liest ein Array von String-Werten aus den Spalten ab einer Zeile der Tabelle aus, nachdem diese konvertiert wurden
// Gibt die Indizes aller Skills zurueck
// cells: Die Zellen einer Zeile
function getIdxAllSkills() {
// colIdxArr: Erster Spaltenindex der gesuchten Werte
    return [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
// arrOrLength: Entweder ein Datenarray zum Fuellen oder die Anzahl der zu lesenden Werte
}
// convertFun: Funktion, die die Werte konvertiert
// return Array mit Spalteneintraegen als String ("" fuer "nicht gefunden")
function convertArrayFromHTML(cells, colIdxArr, arrOrLength = 1, convertFun = sameValue) {
    const __ARR = ((typeof arrOrLength === 'number') ? { } : arrOrLength);
    const __LENGTH = getValue(__ARR.length, arrOrLength);
    const __RET = [];


    for (let index = 0, colIdx = colIdxArr; index < __LENGTH; index++, colIdx++) {
// Gibt die Indizes der trainierbaren Skills zurueck
        const __CELL = getValue(cells[colIdx], { });
function getIdxTrainableSkills() {
        const __TEXT = convertFun(getValue(__ARR[index], __CELL.textContent), __CELL, colIdx, index);
    return [ 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 15 ];
}


        if (__TEXT !== undefined) {
// Gibt die Indizes der Fixskills zurueck
            __CELL.innerHTML = __TEXT;
function getIdxFixSkills() {
        }
    return [ 6, 7, 12, 13, 14, 16 ];
}


        __RET.push(getValue(__TEXT, "").toString());
// Gibt die Indizes der Primaerskills zurueck
function getIdxPriSkills(pos) {
    switch (pos) {
        case 'TOR' : return [ 2, 3, 4, 5 ];
        case 'ABW' : return [ 2, 3, 4, 15 ];
        case 'DMI' : return [ 1, 4, 9, 11 ];
        case 'MIT' : return [ 1, 3, 9, 11 ];
        case 'OMI' : return [ 1, 5, 9, 11 ];
        case 'STU' : return [ 0, 2, 3, 5 ];
        default :    return [];
     }
     }
    return __RET;
}
}


// Konvertiert den Aufwertungstext einer Zelle auf der Jugend-Teamuebersicht
// Gibt die Indizes der (trainierbaren) Sekundaerskills zurueck
// value: Der Inhalt dieser Zeile ("+1 SKI +1 OPT" bzw. "+2 SKI)
function getIdxSecSkills(pos) {
// cell: Zelle, in der der Text stand (optional)
     switch (pos) {
// return Der konvertierte String ("SKI OPT" bzw. "SKI SKI")
         case 'TOR' : return [ 0, 1, 8, 9, 10, 11, 15 ];
function convertAufwertung(value, cell = undefined) {
        case 'ABW' : return [ 0, 1, 5, 8, 9, 10, 11 ];
     if (value !== undefined) {
        case 'DMI' : return [ 0, 2, 3, 5, 8, 10, 15 ];
         value = value.replace(/\+2 (\w+)/, "$1 $1").replace(/\+1 /g, "");
         case 'MIT' : return [ 0, 2, 4, 5, 8, 10, 15 ];
 
        case 'OMI' : return [ 0, 2, 3, 4, 8, 10, 15 ];
         if (cell) {
        case 'STU' : return [ 1, 4, 8, 9, 10, 11, 15 ];
            if (cell.className === 'TOR') {
         default :    return [];
                value = convertGoalieSkill(value);
            }
 
            cell.align = 'left';
         }
     }
     }
    return value;
}
}


// Konvertiert die allgemeinen Skills in die eines Torwarts
// Gibt die zur Position gehoerige Farbe zurueck
// value: Ein Text, der die Skillnamen enthaelt
function getColor(pos) {
// return Der konvertierte String mit Aenderungen (z.B. "FAN" statt "KOB") oder unveraendert
    switch (pos) {
function convertGoalieSkill(value) {
        case 'TOR' : return "#FFFF00";
    if (value !== undefined) {
        case 'ABW' : return "#00FF00";
         value = value.replace(/\w+/g, getGoalieSkill);
        case 'DMI' : return "#3366FF";
        case 'MIT' : return "#66FFFF";
        case 'OMI' : return "#FF66FF";
        case 'STU' : return "#FF0000";
        case 'LEI' : return "#FFFFFF";
         case "" :    return "#111166";  // osBlau
        default :    return "";
     }
     }
    return value;
}
}


// Konvertiert einen Aufwertungstext fuer einen Skillnamen in den fuer einen Torwart
// ==================== Ende Abschnitt genereller Code zur Anzeige der Jugend ====================
// name: Allgemeiner Skillname (abgeleitet von den Feldspielern)
// return Der konvertierte String (z.B. "FAN" statt "KOB") oder unveraendert
function getGoalieSkill(name) {
    const __GOALIESKILLS = {
                              'SCH' : 'ABS',
                              'BAK' : 'STS',
                              'KOB' : 'FAN',
                              'ZWK' : 'STB',
                              'DEC' : 'SPL',
                              'GES' : 'REF'
                          };


    return getValue(__GOALIESKILLS[name], name);
// ==================== Abschnitt fuer interne IDs auf den Seiten ====================
}


// Liest die Aufwertungen eines Spielers aus und konvertiert je nachdem, ob der Spieler Torwart oder Feldspieler ist
const __GAMETYPENRN = {    // "Blind FSS gesucht!"
// cells: Die Zellen einer Zeile
        'unbekannt'  : -1,
// colIdxAuf: Spaltenindex der gesuchten Aufwertungen
        'reserviert' :  0,
// shortForm: true = abgekuerzt, false = Originalform
        'Frei'      :  0,
// return Konvertierte Aufwertungen (kurze oder lange Form, aber in jedem Fall fuer Torwart konvertiert)
        'spielfrei'  :  0,
function getAufwertFromHTML(cells, colIdxAuf, shortForm = true) {
        'Friendly'  :  1,
     const __ISGOALIE = isGoalieFromHTML(cells, colIdxAuf);
        'Liga'      : 2,
        'LP'        : 3,
        'OSEQ'      : 4,
        'OSE'        :  5,
        'OSCQ'      :  6,
        'OSC'        :  7,
        'Supercup'  : 10
     };


    return convertStringFromHTML(cells, colIdxAuf, (shortForm ? convertAufwertung : __ISGOALIE ? convertGoalieSkill : undefined));
const __GAMETYPEALIASES = {
}
        'unbekannt'  :  "unbekannt",
        'reserviert' :  undefined,
        'Frei'      :  undefined,
        'spielfrei'  :  "",
        'Friendly'  :  "FSS",
        'Liga'      :  undefined,
        'LP'        :  "Pokal",
        'OSEQ'      :  undefined,
        'OSE'        :  undefined,
        'OSCQ'      : undefined,
        'OSC'        : undefined,
        'Supercup'  : "Super"
    };
const __GAMETYPES = reverseMapping(__GAMETYPENRN);


// Identitaetsfunktion. Konvertiert nichts, sondern liefert einfach den Wert zurueck
const __LIGANRN = {
// value: Der uebergebene Wert
        'unbekannt'  :  0,
// return Derselbe Wert
        '1. Liga'    :  1,
function sameValue(value) {
        '2. Liga A'  : 2,
     return value;
        '2. Liga B'  :  3,
}
        '3. Liga A'  :  4,
        '3. Liga B'  :  5,
        '3. Liga C'  :  6,
        '3. Liga D'  :  7
     };
const __LIGATYPES = reverseMapping(__LIGANRN);


// Existenzfunktion. Liefert zurueck, ob ein Wert belegt ist
const __LANDNRN = {
// value: Der uebergebene Wert
        'unbekannt'              :  0,
// return Angabe ob Wert belegt ist
        'Albanien'              :  45,
function existValue(value) {
        'Andorra'                :  95,
    return !! value;
        'Armenien'              :  83,
}
        'Aserbaidschan'          : 104,
 
        'Belgien'                :  12,
// Liefert den ganzzeiligen Anteil einer Zahl zurueck, indem alles hinter einem Punkt abgeschnitten wird
        'Bosnien-Herzegowina'    :  66,
// value: Eine uebergebene Dezimalzahl
        'Bulgarien'              :  42,
// return Der ganzzeilige Anteil dieser Zahl
        'D\xE4nemark'            :  8,
function floorValue(value, dot = '.') {
        'Deutschland'            :  6,
    if ((value === 0) || (value && isFinite(value))) {
        'England'                :  1,
         const __VALUE = value.toString();
        'Estland'                :  57,
         const __INDEXDOT = (__VALUE ? __VALUE.indexOf(dot) : -1);
        'Far\xF6er'              :  68,
 
        'Finnland'              :  40,
         return Number((~ __INDEXDOT) ? __VALUE.substring(0, __INDEXDOT) : __VALUE);
        'Frankreich'            :  32,
    } else {
        'Georgien'              : 49,
         return value;
        'Griechenland'          :  30,
    }
        'Irland'                :  5,
}
        'Island'                :  29,
 
        'Israel'                :  23,
// Liefert einen rechtsbuendigen Text zurueck, der links aufgefuellt wird
        'Italien'                :  10,
// value: Ein uebergebener Wert
        'Kasachstan'            : 105,
// size: Zielbreite (clipping fuer < 0: Abschneiden, falls zu lang)
        'Kroatien'              :  24,
// char: Zeichen zum Auffuellen
        'Lettland'              :  97,
// return Ein String, der mindestens |size| lang ist (oder genau, falls size < 0, also clipping)
        'Liechtenstein'          :  92,
function padLeft(value, size = 4, char = ' ') {
        'Litauen'                :  72,
    const __SIZE = Math.abs(size);
        'Luxemburg'              : 93,
     const __CLIP = (size < 0);
        'Malta'                  :  69,
    const __VALUE = (value ? value.toString() : "");
        'Mazedonien'            :  86,
    let i = __VALUE.length;
        'Moldawien'             :  87,
    let str = "";
        'Niederlande'            :  11,
         'Nordirland'            :  4,
         'Norwegen'              :   9,
        '\xD6sterreich'          :  14,
         'Polen'                  :  25,
        'Portugal'              : 17,
        'Rum\xE4nien'            :  28,
         'Russland'              :  19,
        'San Marino'            :  98,
        'Schottland'            :  2,
        'Schweden'              :  27,
        'Schweiz'                :  37,
        'Serbien und Montenegro' : 41,
        'Slowakei'              : 70,
        'Slowenien'              : 21,
        'Spanien'                : 13,
        'Tschechien'            :  18,
        'T\xFCrkei'              :  39,
        'Ukraine'                :  20,
        'Ungarn'                :  26,
        'Wales'                  :  3,
        'Weissrussland'         :  71,
        'Zypern'                :  38
     };
const __LAENDER = reverseMapping(__LANDNRN);


     while (i < __SIZE) {
const __TLALAND = {
         str += char;
        undefined : 'unbekannt',
         i += char.length;
        'ALB'     : 'Albanien',
     }
         'AND'    : 'Andorra',
     str = ((i > __SIZE) ? str.slice(0, __SIZE - __VALUE.length - 1) : str) + __VALUE;
         'ARM'    : 'Armenien',
 
        'AZE'     : 'Aserbaidschan',
     return (__CLIP ? str.slice(size) : str);
        'BEL'     : 'Belgien',
}
        'BIH'    : 'Bosnien-Herzegowina',
 
        'BUL'    : 'Bulgarien',
// Liefert eine rechtsbuendigen Zahl zurueck, der links (mit Nullen) aufgefuellt wird
        'DEN'    : 'D\xE4nemark',
// value: Eine uebergebene Zahl
        'GER'    : 'Deutschland',
// size: Zielbreite (Default: 2)
        'ENG'    : 'England',
// char: Zeichen zum Auffuellen (Default: '0')
        'EST'    : 'Estland',
// forceClip: Abschneiden erzwingen, falls zu lang?
        'FRO'    : 'Far\xF6er',
// return Eine Zahl als String, der mindestens 'size' lang ist (oder genau, falls size < 0, also clipping)
        'FIN'    : 'Finnland',
function padNumber(value, size = 2, char = '0') {
        'FRA'    : 'Frankreich',
     if ((value === 0) || (value && isFinite(value))) {
        'GEO'    : 'Georgien',
         return padLeft(value, size, char);
        'GRE'     : 'Griechenland',
     } else {
        'IRL'    : 'Irland',
         return value;
        'ISL'    : 'Island',
     }
        'ISR'    : 'Israel',
}
        'ITA'    : 'Italien',
 
        'KAZ'    : 'Kasachstan',
// Hilfsfunktionen **********************************************************************
        'CRO'    : 'Kroatien',
 
        'LVA'    : 'Lettland',
// Sortiert das Positionsfeld per BubbleSort
        'LIE'    : 'Liechtenstein',
function sortPositionArray(array) {
        'LTU'    : 'Litauen',
     const __TEMP = [];
        'LUX'    : 'Luxemburg',
     let transposed = true;
        'MLT'    : 'Malta',
     // TOR soll immer die letzte Position im Feld sein, deshalb - 1
        'MKD'    : 'Mazedonien',
     let length = array.length - 1;
        'MDA'    : 'Moldawien',
 
        'NED'    : 'Niederlande',
     while (transposed && (length > 1)) {
        'NIR'    : 'Nordirland',
         transposed = false;
        'NOR'     : 'Norwegen',
         for (let i = 0; i < length - 1; i++) {
         'AUT'    : '\xD6sterreich',
            // Vergleich Opti-Werte:
        'POL'    : 'Polen',
            if (array[i][1] < array[i + 1][1]) {
        'POR'     : 'Portugal',
                // vertauschen
         'ROM'    : 'Rum\xE4nien',
                __TEMP[0] = array[i][0];
        'RUS'     : 'Russland',
                __TEMP[1] = array[i][1];
        'SMR'    : 'San Marino',
                array[i][0] = array[i + 1][0];
        'SCO'    : 'Schottland',
                array[i][1] = array[i + 1][1];
        'SWE'    : 'Schweden',
                array[i + 1][0] = __TEMP[0];
        'SUI'    : 'Schweiz',
                array[i + 1][1] = __TEMP[1];
        'SCG'    : 'Serbien und Montenegro',
                transposed = true;
        'SVK'    : 'Slowakei',
            }
        'SVN'     : 'Slowenien',
        }
        'ESP'     : 'Spanien',
        length--;
        'CZE'     : 'Tschechien',
     }
        'TUR'     : 'T\xFCrkei',
        'UKR'    : 'Ukraine',
        'HUN'     : 'Ungarn',
         'WAL'    : 'Wales',
         'BLR'    : 'Weissrussland',
        'CYP'    : 'Zypern'
    };
const __LANDTLAS = reverseMapping(__TLALAND);
 
// ==================== Abschnitt fuer Daten des Spielplans ====================
 
// Gibt die ID fuer den Namen eines Wettbewerbs zurueck
// gameType: Name des Wettbewerbs eines Spiels
// defValue: Default-Wert
// return OS2-ID fuer den Spieltyp (1 bis 7 oder 10), 0 fuer "spielfrei"/"Frei"/"reserviert", -1 fuer ungueltig
function getGameTypeID(gameType, defValue = __GAMETYPENRN.unbekannt) {
     return getValue(__GAMETYPENRN[gameType], defValue);
}
}


// Schaut nach, ob der uebergebene Index zu einem trainierbaren Skill gehoert
// Gibt den Namen eines Wettbewerbs zurueck
// Die Indizes gehen von 0 (SCH) bis 16 (EIN)
// id: OS2-ID des Wettbewerbs eines Spiels (1 bis 7 oder 10), 0 fuer "spielfrei"/"Frei"/"reserviert", -1 fuer ungueltig
function isTrainableSkill(idx) {
// defValue: Default-Wert
     const __TRAINABLESKILLS = getIdxTrainableSkills();
// return Spieltyp fuer die uebergebene OS2-ID
    const __IDX = parseInt(idx, 10);
function getGameType(id, defValue) {
    let result = false;
     return getValue(__GAMETYPES[id], defValue);
 
    for (let idxTrainable of __TRAINABLESKILLS) {
        if (__IDX === idxTrainable) {
            result = true;
            break;
        }
    }
 
    return result;
}
}


// Gibt alle Skill-Namen zurueck
// Gibt den alternativen (Kurznamen) fuer den Namen eines Wettbewerbs zurueck
function getAllSkillNames(isGoalie = false) {
// gameType: Name des Wettbewerbs eines Spiels
     if (isGoalie) {
// return Normalerweise den uebergebenen Parameter, in Einzelfaellen eine Kurzversion
        return [ 'ABS', 'STS', 'FAN', 'STB', 'SPL', 'REF', 'FUQ', 'ERF', 'AGG', 'PAS', 'AUS', 'UEB', 'WID', 'SEL', 'DIS', 'ZUV', 'EIN' ];
function getGameTypeAlias(gameType) {
    } else {
     return getValue(__GAMETYPEALIASES[gameType], getValue(gameType, __GAMETYPEALIASES.unbekannt));
        return [ 'SCH', 'BAK', 'KOB', 'ZWK', 'DEC', 'GES', 'FUQ', 'ERF', 'AGG', 'PAS', 'AUS', 'UEB', 'WID', 'SEL', 'DIS', 'ZUV', 'EIN' ];
    }
}
}


// Gibt den Skill-Namen zu einem Index zurueck
// Gibt den Namen des Landes mit dem uebergebenen Kuerzel (TLA) zurueck.
function getSkillName(idx, isGoalie = false) {
// tla: Kuerzel (TLA) des Landes
     const __ALLNAMES = getAllSkillNames(isGoalie);
// defValue: Default-Wert
 
// return Name des Landes, 'unbekannt' fuer undefined
    return __ALLNAMES[idx];
function getLandName(tla, defValue = __TLALAND[undefined]) {
     return getValue(__TLALAND[tla], defValue);
}
}


// Gibt den Skill-Namen zu einem Index-Array zurueck
// Gibt die ID des Landes mit dem uebergebenen Namen zurueck.
function getSkillNameArray(idxArr, isGoalie = false) {
// land: Name des Landes
     return (idxArr ? idxArr.map(function(item) {
// defValue: Default-Wert
                                    return getSkillName(item, isGoalie);
// return OS2-ID des Landes, 0 fuer ungueltig
                                }) : idxArr);
function getLandNr(land, defValue = __LANDNRN.unbekannt) {
     return getValue(__LANDNRN[land], defValue);
}
}


// Gibt die Indizes aller Skills zurueck
// Gibt die ID der Liga mit dem uebergebenen Namen zurueck.
function getIdxAllSkills() {
// land: Name der Liga
     return [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ];
// defValue: Default-Wert
// return OS2-ID der Liga, 0 fuer ungueltig
function getLigaNr(liga, defValue = __LIGANRN.unbekannt) {
     return getValue(__LIGANRN[liga], defValue);
}
}


// Gibt die Indizes der trainierbaren Skills zurueck
// Kehrt das Mapping eines Objekts um und liefert ein neues Objekt zurueck.
function getIdxTrainableSkills() {
// obj: Objekt mit key => value
     return [ 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 15 ];
// convFun: Konvertierfunktion fuer die Werte
}
// return Neues Objekt mit value => key (doppelte value-Werte fallen heraus!)
function reverseMapping(obj, convFun) {
     if (! obj) {
        return obj;
    }
 
    const __RET = { };


// Gibt die Indizes der Fixskills zurueck
    for (let key in obj) {
function getIdxFixSkills() {
        const __VALUE = obj[key];
    return [ 6, 7, 12, 13, 14, 16 ];
}


// Gibt die Indizes der Primaerskills zurueck
        __RET[__VALUE] = (convFun ? convFun(key) : key);
function getIdxPriSkills(pos) {
    switch (pos) {
        case 'TOR' : return [ 2, 3, 4, 5 ];
        case 'ABW' : return [ 2, 3, 4, 15 ];
        case 'DMI' : return [ 1, 4, 9, 11 ];
        case 'MIT' : return [ 1, 3, 9, 11 ];
        case 'OMI' : return [ 1, 5, 9, 11 ];
        case 'STU' : return [ 0, 2, 3, 5 ];
        default :    return [];
     }
     }
}


// Gibt die Indizes der (trainierbaren) Sekundaerskills zurueck
     return __RET;
function getIdxSecSkills(pos) {
     switch (pos) {
        case 'TOR' : return [ 0, 1, 8, 9, 10, 11, 15 ];
        case 'ABW' : return [ 0, 1, 5, 8, 9, 10, 11 ];
        case 'DMI' : return [ 0, 2, 3, 5, 8, 10, 15 ];
        case 'MIT' : return [ 0, 2, 4, 5, 8, 10, 15 ];
        case 'OMI' : return [ 0, 2, 3, 4, 8, 10, 15 ];
        case 'STU' : return [ 1, 4, 8, 9, 10, 11, 15 ];
        default :    return [];
    }
}
}


// Gibt die zur Position gehoerige Farbe zurueck
// ==================== Abschnitt fuer sonstige Parameter ====================
function getColor(pos) {
 
     switch (pos) {
// Formatiert eine Zelle um (mit einfachen Parametern)
         case 'TOR' : return "#FFFF00";
// cell: Zu formatierende Zelle
         case 'ABW' : return "#00FF00";
// bold: Inhalt fett darstellen (true = ja, false = nein)
         case 'DMI' : return "#3366FF";
// color: Falls angegeben, die Schriftfarbe
         case 'MIT' : return "#66FFFF";
// bgColor: Falls angegeben, die Hintergrundfarbe
         case 'OMI' : return "#FF66FF";
// opacity: Falls angegeben, die Opazitaet
         case 'STU' : return "#FF0000";
// return Die formatierte Zelle
         case 'LEI' : return "#FFFFFF";
function formatCell(cell, bold = true, color = undefined, bgColor = undefined, opacity = undefined) {
        case "" :    return "#111166"; // osBlau
     if (cell) {
         default :    return "";
         if (bold) {
            cell.style.fontWeight = 'bold';
         }
         if (color) {
            cell.style.color = color;
         }
         if (bgColor) {
            cell.style.backgroundColor = bgColor;
         }
         if (opacity) {
        cell.style.opacity = opacity;
         }
     }
     }
    return cell;
}
}


// ==================== Ende Abschnitt genereller Code zur Anzeige der Jugend ====================
// Ermittelt die auszugewaehlenden Werte eines Selects (Combo-Box) als Array zurueck
// element: 'select'-Element oder dessen Name auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
// valFun: Funktion zur Ermittlung des Wertes eines 'option'-Eintrags (getSelectedOptionText, getSelectedValue, ...)
// defValue: Default-Wert, falls nichts selektiert ist
// return Array mit den Options-Werten
function getSelectionArray(element, valType = 'String', valFun = getSelectedValue, defValue = undefined) {
    const __SELECT = ((typeof element) === 'string' ? getValue(document.getElementsByName(element), [])[0] : element);


// ==================== Abschnitt fuer interne IDs auf den Seiten ====================
    return (__SELECT ? [].map.call(__SELECT.options, function(option) {
 
                                                        return this[valType](getValue(valFun(option), defValue));
const __GAMETYPENRN = {    // "Blind FSS gesucht!"
                                                    }) : undefined);
        'unbekannt' : -1,
}
        'reserviert' : 0,
 
        'Frei'       :  0,
// Ermittelt den ausgewaehlten Wert eines Selects (Combo-Box) und gibt diesen zurueck
        'spielfrei' :  0,
// element: 'select'-Element oder dessen Name auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
        'Friendly'   :  1,
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
        'Liga'      : 2,
// valFun: Funktion zur Ermittlung des Wertes eines 'option'-Eintrags (getSelectedOptionText, getSelectedValue, ...)
        'LP'        :  3,
// defValue: Default-Wert, falls nichts selektiert ist
        'OSEQ'      :  4,
// return Ausgewaehlter Wert
        'OSE'       :  5,
function getSelection(element, valType = 'String', valFun = getSelectedOptionText, defValue = undefined) {
        'OSCQ'      :  6,
    const __SELECT = ((typeof element) === 'string' ? getValue(document.getElementsByName(element), [])[0] : element);
        'OSC'       :  7,
        'Supercup'  : 10
    };


const __GAMETYPEALIASES = {
     return this[valType](getValue(valFun(__SELECT), defValue));
        'unbekannt'  :  "unbekannt",
}
        'reserviert' :  undefined,
        'Frei'      :  undefined,
        'spielfrei'  :  "",
        'Friendly'  :  "FSS",
        'Liga'      :  undefined,
        'LP'        :  "Pokal",
        'OSEQ'      :  undefined,
        'OSE'        :  undefined,
        'OSCQ'      :  undefined,
        'OSC'        :  undefined,
        'Supercup'  : "Super"
     };
const __GAMETYPES = reverseMapping(__GAMETYPENRN);


const __LIGANRN = {
// Ermittelt den ausgewaehlten Wert einer Combo-Box und gibt diesen zurueck
         'unbekannt' : 0,
// comboBox: Alle 'option'-Eintraege der Combo-Box
        '1. Liga'   1,
// defValue: Default-Wert, falls nichts selektiert ist
         '2. Liga A'  : 2,
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
         '2. Liga B' : 3,
// return Ausgewaehlter Wert
         '3. Liga A'  : 4,
function getSelectionFromComboBox(comboBox, defValue = undefined, valType = 'String') {
         '3. Liga B' : 5,
    let selection;
         '3. Liga C' : 6,
 
         '3. Liga D' : 7
    for (let i = 0; i < comboBox.length; i++) {
        const __ENTRY = comboBox[i];
 
        if (__ENTRY.outerHTML.match(/selected/)) {
            selection = __ENTRY.textContent;
         }
    }
 
    return this[valType](getValue(selection, defValue));
}
 
// Liefert den Text (textContent) einer selektierten Option
// element: 'select'-Element auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
// return Wert der Selektion (textContent)
function getSelectedOptionText(element) {
    const __SELECTEDOPTIONS = getValue(element, { }).selectedOptions;
    const __OPTION = getValue(__SELECTEDOPTIONS, { })[0];
 
    return (__OPTION ? __OPTION.textContent : undefined);
}
 
// Liefert den 'value' einer selektierten Option
// element: 'select'-Element auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
// return Wert der Selektion ('value')
function getSelectedValue(element) {
    return getValue(element, { }).value;
}
 
// ==================== Ende Abschnitt fuer sonstige Parameter ====================
 
// ==================== Abschnitt fuer sonstige Parameter des Spielplans ====================
 
const __TEAMSEARCHHAUPT = { // Parameter zum Team "<b>Willkommen im Managerb&uuml;ro von TEAM</b><br>LIGA LAND<a href=..."
         'Zeile'  : 0,
         'Spalte' : 1,
         'start'  : " von ",
         'middle' : "</b><br>",
         'liga'  : ". Liga",
        'land'  : ' ',
         'end'   : "<a href="
     };
     };
const __LIGATYPES = reverseMapping(__LIGANRN);


const __LANDNRN = {
const __TEAMSEARCHTEAM = { // Parameter zum Team "<b>TEAM - LIGA <a href=...>LAND</a></b>"
         'unbekannt'             :   0,
         'Zeile' : 0,
         'Albanien'               : 45,
         'Spalte' : 0,
         'Andorra'               : 95,
         'start'  : "<b>",
        'Armenien'              : 83,
         'middle' : " - ",
         'Aserbaidschan'         : 104,
         'liga'   : ". Liga",
        'Belgien'                :  12,
         'land'   : 'target="_blank">',
        'Bosnien-Herzegowina'    :  66,
         'end'   : "</a></b>"
         'Bulgarien'             : 42,
    };
         'D\xE4nemark'           :   8,
 
        'Deutschland'           :  6,
// Ermittelt, wie das eigene Team heisst und aus welchem Land bzw. Liga es kommt (zur Unterscheidung von Erst- und Zweitteam)
         'England'               :   1,
// cell: Tabellenzelle mit den Parametern zum Team "startTEAMmiddleLIGA...landLANDend", LIGA = "#liga[ (A|B|C|D)]"
        'Estland'                :  57,
// teamSeach: Muster fuer die Suche, die Eintraege fuer 'start', 'middle', 'liga', 'land' und 'end' enthaelt
        'Far\xF6er'              :  68,
// return Im Beispiel { 'Team' : "TEAM", 'Liga' : "LIGA", 'Land' : "LAND", 'LdNr' : LAND-NUMMER, 'LgNr' : LIGA-NUMMER },
        'Finnland'              :  40,
//        z.B. { 'Team' : "Choromonets Odessa", 'Liga' : "1. Liga", 'Land' : "Ukraine", 'LdNr' : 20, 'LgNr' : 1 }
        'Frankreich'            : 32,
function getTeamParamsFromTable(table, teamSearch = undefined) {
        'Georgien'              : 49,
    const __TEAMSEARCH   = getValue(teamSearch, __TEAMSEARCHHAUPT);
        'Griechenland'           :  30,
    const __TEAMCELLROW = getValue(__TEAMSEARCH.Zeile, 0);
        'Irland'                 :  5,
    const __TEAMCELLCOL = getValue(__TEAMSEARCH.Spalte, 0);
        'Island'                 :  29,
    const __TEAMCELLSTR = (table === undefined) ? "" : table.rows[__TEAMCELLROW].cells[__TEAMCELLCOL].innerHTML;
        'Israel'                 :  23,
    const __SEARCHSTART = __TEAMSEARCH.start;
        'Italien'               :  10,
    const __SEARCHMIDDLE = __TEAMSEARCH.middle;
        'Kasachstan'             : 105,
    const __SEARCHLIGA   = __TEAMSEARCH.liga;
        'Kroatien'               : 24,
    const __SEARCHLAND  = __TEAMSEARCH.land;
        'Lettland'               : 97,
    const __SEARCHEND    = __TEAMSEARCH.end;
        'Liechtenstein'         : 92,
    const __INDEXSTART  = __TEAMCELLSTR.indexOf(__SEARCHSTART);
        'Litauen'               : 72,
    const __INDEXEND    = __TEAMCELLSTR.indexOf(__SEARCHEND);
        'Luxemburg'             : 93,
 
        'Malta'                 : 69,
    let teamParams = __TEAMCELLSTR.substring(__INDEXSTART + __SEARCHSTART.length, __INDEXEND);
        'Mazedonien'             : 86,
    const __INDEXLIGA = teamParams.indexOf(__SEARCHLIGA);
        'Moldawien'             : 87,
    const __INDEXMIDDLE = teamParams.indexOf(__SEARCHMIDDLE);
        'Niederlande'           : 11,
 
        'Nordirland'            :  4,
    let land = ((~ __INDEXLIGA) ? teamParams.substring(__INDEXLIGA + __SEARCHLIGA.length) : undefined);
        'Norwegen'              :   9,
    const __TEAMNAME = ((~ __INDEXMIDDLE) ? teamParams.substring(0, __INDEXMIDDLE) : undefined);
        '\xD6sterreich'          : 14,
     let liga = (((~ __INDEXLIGA) && (~ __INDEXMIDDLE)) ? teamParams.substring(__INDEXMIDDLE + __SEARCHMIDDLE.length) : undefined);
        'Polen'                  : 25,
        'Portugal'              : 17,
        'Rum\xE4nien'            : 28,
        'Russland'              : 19,
        'San Marino'            :  98,
        'Schottland'            :   2,
        'Schweden'              :  27,
        'Schweiz'                :  37,
        'Serbien und Montenegro' :  41,
        'Slowakei'              :  70,
        'Slowenien'              :  21,
        'Spanien'                :  13,
        'Tschechien'            :  18,
        'T\xFCrkei'              :  39,
        'Ukraine'                :  20,
        'Ungarn'                :  26,
        'Wales'                  :   3,
        'Weissrussland'          :  71,
        'Zypern'                : 38
     };
const __LAENDER = reverseMapping(__LANDNRN);


const __TLALAND = {
    if (land !== undefined) {
         undefined : 'unbekannt',
         if (land.charAt(2) === ' ') {    // Land z.B. hinter "2. Liga A " statt "1. Liga "
        'ALB'    : 'Albanien',
            land = land.substr(2);
         'AND'    : 'Andorra',
         }
         'ARM'    : 'Armenien',
         if (liga !== undefined) {
        'AZE'    : 'Aserbaidschan',
            liga = liga.substring(0, liga.length - land.length);
        'BEL'    : 'Belgien',
         }
        'BIH'    : 'Bosnien-Herzegowina',
         const __INDEXLAND = land.indexOf(__SEARCHLAND);
         'BUL'    : 'Bulgarien',
         if (~ __INDEXLAND) {
         'DEN'    : 'D\xE4nemark',
            land = land.substr(__INDEXLAND + __SEARCHLAND.length);
         'GER'    : 'Deutschland',
         }
        'ENG'    : 'England',
     }
         'EST'    : 'Estland',
 
        'FRO'     : 'Far\xF6er',
     const __TEAM = new Team(__TEAMNAME, land, liga);
        'FIN'    : 'Finnland',
 
        'FRA'    : 'Frankreich',
     return __TEAM;
        'GEO'     : 'Georgien',
}
        'GRE'    : 'Griechenland',
 
        'IRL'    : 'Irland',
// Verarbeitet die URL der Seite und ermittelt die Nummer der gewuenschten Unterseite
        'ISL'     : 'Island',
// url: Adresse der Seite
        'ISR'    : 'Israel',
// leafs: Liste von Filenamen mit der Default-Seitennummer (falls Query-Parameter nicht gefunden)
        'ITA'    : 'Italien',
// item: Query-Parameter, der die Nummer der Unterseite angibt
        'KAZ'    : 'Kasachstan',
// return Parameter aus der URL der Seite als Nummer
        'CRO'    : 'Kroatien',
function getPageIdFromURL(url, leafs, item = 'page') {
        'LVA'    : 'Lettland',
     const __URI = new URI(url);
        'LIE'    : 'Liechtenstein',
     const __LEAF = __URI.getLeaf();
        'LTU'    : 'Litauen',
        'LUX'    : 'Luxemburg',
        'MLT'    : 'Malta',
        'MKD'    : 'Mazedonien',
        'MDA'    : 'Moldawien',
        'NED'    : 'Niederlande',
        'NIR'    : 'Nordirland',
        'NOR'    : 'Norwegen',
        'AUT'    : '\xD6sterreich',
        'POL'    : 'Polen',
        'POR'    : 'Portugal',
        'ROM'    : 'Rum\xE4nien',
        'RUS'    : 'Russland',
        'SMR'    : 'San Marino',
        'SCO'    : 'Schottland',
        'SWE'    : 'Schweden',
        'SUI'    : 'Schweiz',
        'SCG'    : 'Serbien und Montenegro',
        'SVK'    : 'Slowakei',
        'SVN'    : 'Slowenien',
        'ESP'    : 'Spanien',
        'CZE'    : 'Tschechien',
        'TUR'    : 'T\xFCrkei',
        'UKR'    : 'Ukraine',
        'HUN'    : 'Ungarn',
        'WAL'     : 'Wales',
        'BLR'     : 'Weissrussland',
        'CYP'     : 'Zypern'
    };
const __LANDTLAS = reverseMapping(__TLALAND);


// ==================== Abschnitt fuer Daten des Spielplans ====================
    for (let leaf in leafs) {
        if (__LEAF === leaf) {
            const __DEFAULT = leafs[leaf];


// Gibt die ID fuer den Namen eines Wettbewerbs zurueck
            return getValue(__URI.getQueryPar(item), __DEFAULT);
// gameType: Name des Wettbewerbs eines Spiels
        }
// defValue: Default-Wert
    }
// return OS2-ID fuer den Spieltyp (1 bis 7 oder 10), 0 fuer "spielfrei"/"Frei"/"reserviert", -1 fuer ungueltig
function getGameTypeID(gameType, defValue = __GAMETYPENRN.unbekannt) {
    return getValue(__GAMETYPENRN[gameType], defValue);
}


// Gibt den Namen eines Wettbewerbs zurueck
    return -1;
// id: OS2-ID des Wettbewerbs eines Spiels (1 bis 7 oder 10), 0 fuer "spielfrei"/"Frei"/"reserviert", -1 fuer ungueltig
// defValue: Default-Wert
// return Spieltyp fuer die uebergebene OS2-ID
function getGameType(id, defValue) {
    return getValue(__GAMETYPES[id], defValue);
}
}


// Gibt den alternativen (Kurznamen) fuer den Namen eines Wettbewerbs zurueck
// Gibt die laufende Nummer des ZATs im Text einer Zelle zurueck
// gameType: Name des Wettbewerbs eines Spiels
// cell: Tabellenzelle mit der ZAT-Nummer im Text
// return Normalerweise den uebergebenen Parameter, in Einzelfaellen eine Kurzversion
// return ZAT-Nummer im Text
function getGameTypeAlias(gameType) {
function getZATNrFromCell(cell) {
     return getValue(__GAMETYPEALIASES[gameType], getValue(gameType, __GAMETYPEALIASES.unbekannt));
     const __TEXT = ((cell === undefined) ? [] : cell.textContent.split(' '));
}
    let ZATNr = 0;


// Gibt den Namen des Landes mit dem uebergebenen Kuerzel (TLA) zurueck.
    for (let i = 1; (ZATNr === 0) && (i < __TEXT.length); i++) {
// tla: Kuerzel (TLA) des Landes
        if (__TEXT[i - 1] === "ZAT") {
// defValue: Default-Wert
            if (__TEXT[i] !== "ist") {
// return Name des Landes, 'unbekannt' fuer undefined
                ZATNr = parseInt(__TEXT[i], 10);
function getLandName(tla, defValue = __TLALAND[undefined]) {
            }
    return getValue(__TLALAND[tla], defValue);
        }
}
    }


// Gibt die ID des Landes mit dem uebergebenen Namen zurueck.
     return ZATNr;
// land: Name des Landes
// defValue: Default-Wert
// return OS2-ID des Landes, 0 fuer ungueltig
function getLandNr(land, defValue = __LANDNRN.unbekannt) {
     return getValue(__LANDNRN[land], defValue);
}
}


// Gibt die ID der Liga mit dem uebergebenen Namen zurueck.
// ==================== Ende Abschnitt fuer sonstige Parameter des Spielplans ====================
// land: Name der Liga
// defValue: Default-Wert
// return OS2-ID der Liga, 0 fuer ungueltig
function getLigaNr(liga, defValue = __LIGANRN.unbekannt) {
    return getValue(__LIGANRN[liga], defValue);
}


// Kehrt das Mapping eines Objekts um und liefert ein neues Objekt zurueck.
// ==================== Ende Abschnitt fuer Spielplan und ZATs ====================
// obj: Objekt mit key => value
// convFun: Konvertierfunktion fuer die Werte
// return Neues Objekt mit value => key (doppelte value-Werte fallen heraus!)
function reverseMapping(obj, convFun) {
    if (! obj) {
        return obj;
    }


    const __RET = { };
// ==================== Hauptprogramm ====================


    for (let key in obj) {
// Verarbeitet Ansicht "Haupt" (Managerbuero) zur Ermittlung des aktuellen ZATs
        const __VALUE = obj[key];
function procHaupt() {
    const __TEAMPARAMS = getTeamParamsFromTable(getTable(1), __TEAMSEARCHHAUPT); // Link mit Team, Liga, Land...


        __RET[__VALUE] = (convFun ? convFun(key) : key);
    return buildOptions(__OPTCONFIG, __OPTSET, {
    }
                            'teamParams' : __TEAMPARAMS,
//                            'menuAnchor' : getTable(0, 'div'),
                            'hideMenu'  : true,
                            'showForm'  : {
                                'zeigeWarnung'      : true,
                                'zeigeWarnungMonat'  : true,
                                'zeigeWarnungHome'  : true,
                                'zeigeWarnungDialog' : true,
                                'ziehAnz'            : true,
                                'showForm'          : true
                            }


    return __RET;
                        }).then(async optSet => {
}
            const __ZATCELL = getProp(getProp(getRows(0), 2), 'cells', { })[0];
            const __NEXTZAT = getZATNrFromCell(__ZATCELL);  // "Der naechste ZAT ist ZAT xx und ..."
            const __CURRZAT = __NEXTZAT - 1;
            const __DATAZAT = getOptValue(__OPTSET.datenZat);


// ==================== Abschnitt fuer sonstige Parameter ====================
            // Stand der alten Daten merken...
            setOpt(__OPTSET.oldDatenZat, __DATAZAT, false);


// Formatiert eine Zelle um (mit einfachen Parametern)
             if (__CURRZAT >= 0) {
// cell: Zu formatierende Zelle
                __LOG[2]("Aktueller ZAT: " + __CURRZAT);
// bold: Inhalt fett darstellen (true = ja, false = nein)
// color: Falls angegeben, die Schriftfarbe
// bgColor: Falls angegeben, die Hintergrundfarbe
// opacity: Falls angegeben, die Opazitaet
// return Die formatierte Zelle
function formatCell(cell, bold = true, color = undefined, bgColor = undefined, opacity = undefined) {
    if (cell) {
        if (bold) {
             cell.style.fontWeight = 'bold';
        }
        if (color) {
            cell.style.color = color;
        }
        if (bgColor) {
            cell.style.backgroundColor = bgColor;
        }
        if (opacity) {
        cell.style.opacity = opacity;
        }
    }


    return cell;
                // Neuen aktuellen ZAT speichern...
}
                setOpt(__OPTSET.aktuellerZat, __CURRZAT, false);


// Ermittelt die auszugewaehlenden Werte eines Selects (Combo-Box) als Array zurueck
                if (__CURRZAT !== __DATAZAT) {
// element: 'select'-Element oder dessen Name auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
                    __LOG[2](__LOG.changed(__DATAZAT, __CURRZAT));
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
 
// valFun: Funktion zur Ermittlung des Wertes eines 'option'-Eintrags (getSelectedOptionText, getSelectedValue, ...)
                    // ... und ZAT-bezogene Daten als veraltet markieren (ausser 'skills', 'positions' und 'ziehAnz')
// defValue: Default-Wert, falls nichts selektiert ist
                    await __TEAMCLASS.deleteOptions({
// return Array mit den Options-Werten
                                                    'skills'     : true,
function getSelectionArray(element, valType = 'String', valFun = getSelectedValue, defValue = undefined) {
                                                    'positions'   : true,
    const __SELECT = ((typeof element) === 'string' ? getValue(document.getElementsByName(element), [])[0] : element);
                                                    'datenZat'   : true,
                                                    'oldDatenZat' : true,
                                                    'ziehAnz'     : (__CURRZAT > __DATAZAT) // nur loeschen, wenn < __DATAZAT
                                                }).catch(defaultCatch);


    return (__SELECT ? [].map.call(__SELECT.options, function(option) {
                    // Neuen Daten-ZAT speichern...
                                                        return this[valType](getValue(valFun(option), defValue));
                    setOpt(__OPTSET.datenZat, __CURRZAT, false);
                                                    }) : undefined);
                }
}
            }


// Ermittelt den ausgewaehlten Wert eines Selects (Combo-Box) und gibt diesen zurueck
            const __WARNHOME = getOptValue(optSet.zeigeWarnungHome, true);
// element: 'select'-Element oder dessen Name auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
            const __WARNDIALOG = getOptValue(optSet.zeigeWarnungDialog, false);
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
// valFun: Funktion zur Ermittlung des Wertes eines 'option'-Eintrags (getSelectedOptionText, getSelectedValue, ...)
// defValue: Default-Wert, falls nichts selektiert ist
// return Ausgewaehlter Wert
function getSelection(element, valType = 'String', valFun = getSelectedOptionText, defValue = undefined) {
    const __SELECT = ((typeof element) === 'string' ? getValue(document.getElementsByName(element), [])[0] : element);


    return this[valType](getValue(valFun(__SELECT), defValue));
            if (__WARNHOME || __WARNDIALOG) {
}
                const __WARN = getOptValue(optSet.zeigeWarnung, true);
                const __WARNMONAT = getOptValue(optSet.zeigeWarnungMonat, true);
                const __ZIEHANZ = getOptValue(optSet.ziehAnz, []);
                const __INDEX = parseInt(__CURRZAT / 6);
                const __REST = 5 - (__CURRZAT % 6);
                const __ANZAHL = __ZIEHANZ[__INDEX];


// Ermittelt den ausgewaehlten Wert einer Combo-Box und gibt diesen zurueck
                if (__ANZAHL > 0) {
// comboBox: Alle 'option'-Eintraege der Combo-Box
                    const __MSG = { };
// defValue: Default-Wert, falls nichts selektiert ist
// valType: Typ-Klasse der Optionswerte ('String', 'Number', ...)
// return Ausgewaehlter Wert
function getSelectionFromComboBox(comboBox, defValue = undefined, valType = 'String') {
    let selection;


    for (let i = 0; i < comboBox.length; i++) {
                    __MSG.text = "ZAT " + ((__INDEX + 1) * 6) + ' ' + ((__ANZAHL > 1) ? "m\xFCssen " + __ANZAHL : "muss einer") + " deiner Jugendspieler in das Profiteam \xFCbernommen werden!";
        const __ENTRY = comboBox[i];


        if (__ENTRY.outerHTML.match(/selected/)) {
                    if (__WARNMONAT && (__REST > 0)) {
            selection = __ENTRY.textContent;
                        __MSG.label = "Warnung";
        }
                        __MSG.when = "Bis zur n\xE4chsten Abrechnung am ";
    }
                    } else if ((__WARN || __WARNMONAT) && (__REST === 0)) {
                        __MSG.label = "LETZTE WARNUNG VOR DER ABRECHNUNG";
                        __MSG.when = "Bis zum n\xE4chsten ";
                    }


    return this[valType](getValue(selection, defValue));
                    if (__MSG.when) {
}
                        if (__WARNHOME) {
                            const __ANCHOR = getTable(0, 'tbody');


// Liefert den Text (textContent) einer selektierten Option
                            __ANCHOR.innerHTML += "<tr><tr>&nbsp;</tr><td class='STU'><b><a href='ju.php'>" + __MSG.label + ": " + __MSG.when + __MSG.text + "</a></b></td></tr><tr>&nbsp;</tr>";
// element: 'select'-Element auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
                        }
// return Wert der Selektion (textContent)
                        if (__WARNDIALOG && (__REST === 0)) {
function getSelectedOptionText(element) {
                             showAlert(__MSG.label, __MSG.when + __MSG.text);
    const __SELECTEDOPTIONS = getValue(element, { }).selectedOptions;
                        }
    const __OPTION = getValue(__SELECTEDOPTIONS, { })[0];
                     }
 
    return (__OPTION ? __OPTION.textContent : undefined);
}
 
// Liefert den 'value' einer selektierten Option
// element: 'select'-Element auf der HTML-Seite mit 'option'-Eintraegen der Combo-Box
// return Wert der Selektion ('value')
function getSelectedValue(element) {
    return getValue(element, { }).value;
}
 
// ==================== Ende Abschnitt fuer sonstige Parameter ====================
 
// ==================== Abschnitt fuer sonstige Parameter des Spielplans ====================
 
const __TEAMSEARCHHAUPT = {  // Parameter zum Team "<b>Willkommen im Managerb&uuml;ro von TEAM</b><br>LIGA LAND<a href=..."
        'Zeile' : 0,
        'Spalte' : 1,
        'start'  : " von ",
        'middle' : "</b><br>",
        'liga'   : ". Liga",
        'land'  : ' ',
        'end'    : "<a href="
    };
 
const __TEAMSEARCHTEAM = {  // Parameter zum Team "<b>TEAM - LIGA <a href=...>LAND</a></b>"
        'Zeile'  : 0,
        'Spalte' : 0,
        'start'  : "<b>",
        'middle' : " - ",
        'liga'  : ". Liga",
        'land'  : 'target="_blank">',
        'end'    : "</a></b>"
    };
 
// Ermittelt, wie das eigene Team heisst und aus welchem Land bzw. Liga es kommt (zur Unterscheidung von Erst- und Zweitteam)
// cell: Tabellenzelle mit den Parametern zum Team "startTEAMmiddleLIGA...landLANDend", LIGA = "#liga[ (A|B|C|D)]"
// teamSeach: Muster fuer die Suche, die Eintraege fuer 'start', 'middle', 'liga', 'land' und 'end' enthaelt
// return Im Beispiel { 'Team' : "TEAM", 'Liga' : "LIGA", 'Land' : "LAND", 'LdNr' : LAND-NUMMER, 'LgNr' : LIGA-NUMMER },
//        z.B. { 'Team' : "Choromonets Odessa", 'Liga' : "1. Liga", 'Land' : "Ukraine", 'LdNr' : 20, 'LgNr' : 1 }
function getTeamParamsFromTable(table, teamSearch = undefined) {
    const __TEAMSEARCH  = getValue(teamSearch, __TEAMSEARCHHAUPT);
    const __TEAMCELLROW  = getValue(__TEAMSEARCH.Zeile, 0);
    const __TEAMCELLCOL  = getValue(__TEAMSEARCH.Spalte, 0);
    const __TEAMCELLSTR  = (table === undefined) ? "" : table.rows[__TEAMCELLROW].cells[__TEAMCELLCOL].innerHTML;
    const __SEARCHSTART  = __TEAMSEARCH.start;
    const __SEARCHMIDDLE = __TEAMSEARCH.middle;
    const __SEARCHLIGA  = __TEAMSEARCH.liga;
    const __SEARCHLAND  = __TEAMSEARCH.land;
    const __SEARCHEND    = __TEAMSEARCH.end;
    const __INDEXSTART  = __TEAMCELLSTR.indexOf(__SEARCHSTART);
    const __INDEXEND    = __TEAMCELLSTR.indexOf(__SEARCHEND);
 
    let teamParams = __TEAMCELLSTR.substring(__INDEXSTART + __SEARCHSTART.length, __INDEXEND);
    const __INDEXLIGA = teamParams.indexOf(__SEARCHLIGA);
    const __INDEXMIDDLE = teamParams.indexOf(__SEARCHMIDDLE);
 
    let land = ((~ __INDEXLIGA) ? teamParams.substring(__INDEXLIGA + __SEARCHLIGA.length) : undefined);
    const __TEAMNAME = ((~ __INDEXMIDDLE) ? teamParams.substring(0, __INDEXMIDDLE) : undefined);
    let liga = (((~ __INDEXLIGA) && (~ __INDEXMIDDLE)) ? teamParams.substring(__INDEXMIDDLE + __SEARCHMIDDLE.length) : undefined);
 
    if (land !== undefined) {
        if (land.charAt(2) === ' ') {    // Land z.B. hinter "2. Liga A " statt "1. Liga "
            land = land.substr(2);
        }
        if (liga !== undefined) {
            liga = liga.substring(0, liga.length - land.length);
        }
        const __INDEXLAND = land.indexOf(__SEARCHLAND);
        if (~ __INDEXLAND) {
            land = land.substr(__INDEXLAND + __SEARCHLAND.length);
        }
    }
 
    const __TEAM = new Team(__TEAMNAME, land, liga);
 
    return __TEAM;
}
 
// Verarbeitet die URL der Seite und ermittelt die Nummer der gewuenschten Unterseite
// url: Adresse der Seite
// leafs: Liste von Filenamen mit der Default-Seitennummer (falls Query-Parameter nicht gefunden)
// item: Query-Parameter, der die Nummer der Unterseite angibt
// return Parameter aus der URL der Seite als Nummer
function getPageIdFromURL(url, leafs, item = 'page') {
    const __URI = new URI(url);
    const __LEAF = __URI.getLeaf();
 
    for (let leaf in leafs) {
        if (__LEAF === leaf) {
            const __DEFAULT = leafs[leaf];
 
            return getValue(__URI.getQueryPar(item), __DEFAULT);
        }
    }
 
    return -1;
}
 
// Gibt die laufende Nummer des ZATs im Text einer Zelle zurueck
// cell: Tabellenzelle mit der ZAT-Nummer im Text
// return ZAT-Nummer im Text
function getZATNrFromCell(cell) {
    const __TEXT = ((cell === undefined) ? [] : cell.textContent.split(' '));
    let ZATNr = 0;
 
    for (let i = 1; (ZATNr === 0) && (i < __TEXT.length); i++) {
        if (__TEXT[i - 1] === "ZAT") {
            if (__TEXT[i] !== "ist") {
                ZATNr = parseInt(__TEXT[i], 10);
            }
        }
    }
 
    return ZATNr;
}
 
// ==================== Ende Abschnitt fuer sonstige Parameter des Spielplans ====================
 
// ==================== Ende Abschnitt fuer Spielplan und ZATs ====================
 
// ==================== Hauptprogramm ====================
 
// Verarbeitet Ansicht "Haupt" (Managerbuero) zur Ermittlung des aktuellen ZATs
function procHaupt() {
    const __TEAMPARAMS = getTeamParamsFromTable(getTable(1), __TEAMSEARCHHAUPT);  // Link mit Team, Liga, Land...
 
    return buildOptions(__OPTCONFIG, __OPTSET, {
                             'teamParams' : __TEAMPARAMS,
//                            'menuAnchor' : getTable(0, 'div'),
                            'hideMenu'  : true,
                            'showForm'  : {
                                              'zeigeWarnung'        : true,
                                              'zeigeWarnungMonat'    : true,
                                              'zeigeWarnungHome'    : true,
                                              'zeigeWarnungDialog'  : true,
                                              'zeigeWarnungAufstieg' : true,
                                              'zeigeWarnungLegende'  : true,
                                              'ziehAnz'              : true,
                                              'showForm'            : true
                                          }
                        }).then(async optSet => {
            const __ZATCELL = getProp(getProp(getRows(0), 2), 'cells', { })[0];
            const __NEXTZAT = getZATNrFromCell(__ZATCELL);  // "Der naechste ZAT ist ZAT xx und ..."
            const __CURRZAT = __NEXTZAT - 1;
            const __DATAZAT = getOptValue(__OPTSET.datenZat);
 
            // Stand der alten Daten merken...
            setOpt(__OPTSET.oldDatenZat, __DATAZAT, false);
 
            if (__CURRZAT >= 0) {
                __LOG[2]("Aktueller ZAT: " + __CURRZAT);
 
                // Neuen aktuellen ZAT speichern...
                setOpt(__OPTSET.aktuellerZat, __CURRZAT, false);
 
                if (__CURRZAT !== __DATAZAT) {
                    __LOG[2](__LOG.changed(__DATAZAT, __CURRZAT));
 
                     // ... und ZAT-bezogene Daten als veraltet markieren (ausser 'skills', 'positions' und 'ziehAnz')
                    await __TEAMCLASS.deleteOptions({
                                                    'skills'      : true,
                                                    'positions'  : true,
                                                    'datenZat'    : true,
                                                    'oldDatenZat' : true,
                                                    'ziehAnz'    : (__CURRZAT > __DATAZAT)  // nur loeschen, wenn < __DATAZAT
                                                }).catch(defaultCatch);
 
                    // Neuen Daten-ZAT speichern...
                    setOpt(__OPTSET.datenZat, __CURRZAT, false);
                 }
                 }
             }
             }
            const __MSG = new WarnDrawMessage(optSet, __CURRZAT);
            const __MSGAUFSTIEG = new WarnDrawMessageAufstieg(optSet, __CURRZAT);
            const __ANCHOR = getTable(0, 'tbody');
            __MSG.showMessage(__ANCHOR, 'tr', true);
            __MSG.showDialog(showAlert);
            __MSGAUFSTIEG.showMessage(__ANCHOR, 'tr', true);
         });
         });
}
}
Zeile 6.298: Zeile 5.941:
                             'getDonation' : true,
                             'getDonation' : true,
                             'showForm'    : {
                             'showForm'    : {
                                                 'foerderung'           : true,
                                                 'foerderung'         : true,
                                                 'zeigeWarnung'         : true,
                                                 'zeigeWarnung'       : true,
                                                 'zeigeWarnungMonat'   : true,
                                                 'zeigeWarnungMonat' : true,
                                                 'zeigeWarnungHome'     : true,
                                                 'zeigeWarnungHome'   : true,
                                                 'zeigeWarnungDialog'  : true,
                                                 'zeigeWarnungDialog' : true,
                                                'zeigeWarnungAufstieg' : true,
                                                 'ziehAnz'           : true,
                                                'zeigeWarnungLegende'  : true,
                                                 'showForm'           : true
                                                 'ziehAnz'             : true,
                                                 'showForm'             : true
                                             }
                                             }
         });
         });
Zeile 6.337: Zeile 5.978:
                                 'menuAnchor' : getTable(0, 'div'),
                                 'menuAnchor' : getTable(0, 'div'),
                                 'showForm'  : {
                                 'showForm'  : {
                                                   'kennzeichenEnde'     : true,
                                                   'kennzeichenEnde'   : true,
                                                   'shortAufw'           : true,
                                                   'shortAufw'         : true,
                                                   'sepStyle'             : true,
                                                   'sepStyle'           : true,
                                                   'sepColor'             : true,
                                                   'sepColor'           : true,
                                                   'sepWidth'             : true,
                                                   'sepWidth'           : true,
                                                   'saison'               : true,
                                                   'saison'             : true,
                                                   'aktuellerZat'         : true,
                                                   'aktuellerZat'       : true,
                                                   'foerderung'           : true,
                                                   'foerderung'         : true,
                                                   'team'                 : true,
                                                   'team'               : true,
                                                   'zeigeJahrgang'       : true,
                                                   'zeigeJahrgang'     : true,
                                                   'zeigeUxx'             : true,
                                                   'zeigeUxx'           : true,
                                                   'zeigeWarnung'         : true,
                                                   'zeigeWarnung'       : true,
                                                   'zeigeWarnungMonat'   : true,
                                                   'zeigeWarnungMonat' : true,
                                                   'zeigeWarnungHome'     : true,
                                                   'zeigeWarnungHome'   : true,
                                                   'zeigeWarnungDialog'   : true,
                                                   'zeigeWarnungDialog' : true,
                                                  'zeigeWarnungAufstieg' : true,
                                                   'zeigeBalken'       : true,
                                                  'zeigeWarnungLegende'  : true,
                                                   'absBalken'         : true,
                                                   'zeigeBalken'         : true,
                                                   'zeigeId'           : true,
                                                   'absBalken'           : true,
                                                   'ersetzeAlter'       : true,
                                                   'zeigeId'             : true,
                                                   'zeigeAlter'         : true,
                                                   'ersetzeAlter'         : true,
                                                   'zeigeQuote'         : true,
                                                   'zeigeAlter'           : true,
                                                   'zeigePosition'     : true,
                                                   'zeigeQuote'           : true,
                                                   'zeigeZatDone'       : true,
                                                   'zeigePosition'       : true,
                                                   'zeigeZatLeft'       : true,
                                                   'zeigeZatDone'         : true,
                                                   'zeigeFixSkills'     : true,
                                                   'zeigeZatLeft'         : true,
                                                   'zeigeTrainiert'     : true,
                                                   'zeigeFixSkills'       : true,
                                                   'zeigeAnteilPri'     : true,
                                                   'zeigeTrainiert'       : true,
                                                   'zeigeAnteilSec'     : true,
                                                   'zeigeAnteilPri'       : true,
                                                   'zeigePrios'         : true,
                                                   'zeigeAnteilSec'       : true,
                                                   'anzahlOpti'         : true,
                                                   'zeigePrios'           : true,
                                                   'anzahlMW'           : true,
                                                   'anzahlOpti'           : true,
                                                   'zeigeTrainiertEnde' : true,
                                                   'anzahlMW'             : true,
                                                   'zeigeAnteilPriEnde' : true,
                                                   'zeigeTrainiertEnde'   : true,
                                                   'zeigeAnteilSecEnde' : true,
                                                   'zeigeAnteilPriEnde'   : true,
                                                   'zeigePriosEnde'     : true,
                                                   'zeigeAnteilSecEnde'   : true,
                                                   'zeigeSkillEnde'     : true,
                                                   'zeigePriosEnde'       : true,
                                                   'anzahlOptiEnde'     : true,
                                                   'zeigeSkillEnde'       : true,
                                                   'anzahlMWEnde'       : true,
                                                   'anzahlOptiEnde'       : true,
                                                   'ziehAnz'           : true,
                                                   'anzahlMWEnde'         : true,
                                                   'zatAges'           : true,
                                                   'ziehAnz'             : true,
                                                   'trainiert'         : true,
                                                   'zatAges'             : true,
                                                   'positions'         : true,
                                                   'trainiert'           : true,
                                                   'skills'             : true,
                                                   'positions'           : true,
                                                   'reset'             : true,
                                                   'skills'               : true,
                                                   'showForm'           : true
                                                   'reset'               : true,
                                                   'showForm'             : true
                                               },
                                               },
                                 'formWidth'  : 1
                                 'formWidth'  : 1
Zeile 6.417: Zeile 6.056:
                     separateGroups(__ROWS, __BORDERSTRING, __COLUMNINDEX.Land, __ROWOFFSETUPPER, __ROWOFFSETLOWER, 0, 0, existValue);
                     separateGroups(__ROWS, __BORDERSTRING, __COLUMNINDEX.Land, __ROWOFFSETUPPER, __ROWOFFSETLOWER, 0, 0, existValue);
                 }
                 }
                const __CURRZAT = getOptValue(__OPTSET.datenZat);
                const __MSG = new WarnDrawMessage(__OPTSET, __CURRZAT);
                const __MSGAUFSTIEG = new WarnDrawMessageAufstieg(__OPTSET, __CURRZAT);
                const __ANCHOR = getTable(0, 'div');
                const __SEARCH = '<form method="POST">';
                // Kompaktere Darstellung und ohne Links...
                __MSG.out.top = false;
                __MSG.out.label = false;
                __MSG.out.link = false;
                __MSG.out.bottom = false;
                __MSGAUFSTIEG.out.label = false;
                __MSGAUFSTIEG.out.link = false;
                __MSGAUFSTIEG.out.bottom = false;
                __MSG.setOptionLegende();
                __MSGAUFSTIEG.setOptionLegende();
                __MSG.showMessage(__ANCHOR, 'p', __SEARCH);
                __MSGAUFSTIEG.showMessage(__ANCHOR, 'p', __SEARCH);
             });
             });
     }
     }
Zeile 6.489: Zeile 6.107:
                                 'menuAnchor' : getTable(0, 'div'),
                                 'menuAnchor' : getTable(0, 'div'),
                                 'hideForm'  : {
                                 'hideForm'  : {
                                                  'zeigeWarnung'        : false,
                                                   'ziehAnz'       : true,
                                                  'zeigeWarnungMonat'    : false,
                                                   'zatAges'       : true,
                                                  'zeigeWarnungHome'    : false,
                                                   'trainiert'     : true,
                                                  'zeigeWarnungDialog'  : false,
                                                   'positions'     : true,
                                                  'zeigeWarnungAufstieg' : false,
                                                   'skills'       : true,
                                                  'zeigeWarnungLegende'  : false,
                                                   'shortAufw'     : true
                                                   'ziehAnz'             : true,
                                                   'zatAges'             : true,
                                                   'trainiert'           : true,
                                                   'positions'           : true,
                                                   'skills'               : true,
                                                   'shortAufw'           : true
                                               },
                                               },
                                 'formWidth'  : 1
                                 'formWidth'  : 1
Zeile 6.560: Zeile 6.172:
                                 'menuAnchor' : getTable(0, 'div'),
                                 'menuAnchor' : getTable(0, 'div'),
                                 'showForm'  : {
                                 'showForm'  : {
                                                   'kennzeichenEnde'     : true,
                                                   'kennzeichenEnde'   : true,
                                                   'sepStyle'             : true,
                                                   'sepStyle'           : true,
                                                   'sepColor'             : true,
                                                   'sepColor'           : true,
                                                   'sepWidth'             : true,
                                                   'sepWidth'           : true,
                                                   'saison'               : true,
                                                   'saison'             : true,
                                                   'aktuellerZat'         : true,
                                                   'aktuellerZat'       : true,
                                                   'foerderung'           : true,
                                                   'foerderung'         : true,
                                                   'team'                 : true,
                                                   'team'               : true,
                                                   'zeigeJahrgang'       : true,
                                                   'zeigeJahrgang'     : true,
                                                   'zeigeUxx'             : true,
                                                   'zeigeUxx'           : true,
                                                   'zeigeWarnung'         : false,
                                                   'zeigeWarnung'       : true,
                                                   'zeigeWarnungMonat'   : false,
                                                   'zeigeWarnungMonat' : true,
                                                   'zeigeWarnungHome'     : false,
                                                   'zeigeWarnungHome'   : true,
                                                   'zeigeWarnungDialog'   : false,
                                                   'zeigeWarnungDialog' : true,
                                                  'zeigeWarnungAufstieg' : false,
                                                   'zeigeBalken'       : true,
                                                  'zeigeWarnungLegende'  : false,
                                                   'absBalken'         : true,
                                                   'zeigeBalken'         : true,
                                                   'zeigeId'           : true,
                                                   'absBalken'           : true,
                                                   'ersetzeAlter'       : true,
                                                   'zeigeId'             : true,
                                                   'zeigeAlter'         : true,
                                                   'ersetzeAlter'         : true,
                                                   'zeigeQuote'         : true,
                                                   'zeigeAlter'           : true,
                                                   'zeigePosition'     : true,
                                                   'zeigeQuote'           : true,
                                                   'zeigeZatDone'       : true,
                                                   'zeigePosition'       : true,
                                                   'zeigeZatLeft'       : true,
                                                   'zeigeZatDone'         : true,
                                                   'zeigeFixSkills'     : true,
                                                   'zeigeZatLeft'         : true,
                                                   'zeigeTrainiert'     : true,
                                                   'zeigeFixSkills'       : true,
                                                   'zeigeAnteilPri'     : true,
                                                   'zeigeTrainiert'       : true,
                                                   'zeigeAnteilSec'     : true,
                                                   'zeigeAnteilPri'       : true,
                                                   'zeigePrios'         : true,
                                                   'zeigeAnteilSec'       : true,
                                                   'zeigeAufw'         : true,
                                                   'zeigePrios'           : true,
                                                   'zeigeGeb'           : true,
                                                   'zeigeAufw'           : true,
                                                   'zeigeTal'           : true,
                                                   'zeigeGeb'             : true,
                                                   'anzahlOpti'         : true,
                                                   'zeigeTal'             : true,
                                                   'anzahlMW'           : true,
                                                   'anzahlOpti'           : true,
                                                   'zeigeTrainiertEnde' : true,
                                                   'anzahlMW'             : true,
                                                   'zeigeAnteilPriEnde' : true,
                                                   'zeigeTrainiertEnde'   : true,
                                                   'zeigeAnteilSecEnde' : true,
                                                   'zeigeAnteilPriEnde'   : true,
                                                   'zeigePriosEnde'     : true,
                                                   'zeigeAnteilSecEnde'   : true,
                                                   'zeigeSkillEnde'     : true,
                                                   'zeigePriosEnde'       : true,
                                                   'anzahlOptiEnde'     : true,
                                                   'zeigeSkillEnde'       : true,
                                                   'anzahlMWEnde'       : true,
                                                   'anzahlOptiEnde'       : true,
                                                   'zatAges'           : true,
                                                   'anzahlMWEnde'         : true,
                                                   'trainiert'         : true,
                                                   'zatAges'             : true,
                                                   'positions'         : true,
                                                   'trainiert'           : true,
                                                   'skills'             : true,
                                                   'positions'           : true,
                                                   'reset'             : true,
                                                   'skills'               : true,
                                                   'showForm'           : true
                                                   'reset'               : true,
                                                   'showForm'             : true
                                               },
                                               },
                                 'formWidth'  : 1
                                 'formWidth'  : 1

Bitte beachte, dass alle Beiträge zu Online-Soccer-Wiki von anderen Mitwirkenden bearbeitet, geändert oder gelöscht werden können. Reiche hier keine Texte ein, falls du nicht willst, dass diese ohne Einschränkung geändert werden können.

Du bestätigst hiermit auch, dass du diese Texte selbst geschrieben hast oder diese von einer gemeinfreien Quelle kopiert hast (weitere Einzelheiten unter Online-Soccer-Wiki:Urheberrechte). ÜBERTRAGE OHNE GENEHMIGUNG KEINE URHEBERRECHTLICH GESCHÜTZTEN INHALTE!

Abbrechen Bearbeitungshilfe (wird in einem neuen Fenster geöffnet)