Bearbeiten von „OS2.haupt

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 1: Zeile 1:
[[Kategorie:Greasemonkey]]
[[Kategorie:Greasemonkey]]
[[Kategorie:Greasemonkey WE]]
{| style="background-color:white; font-size:11px; float: right; margin:3px 3px 3px 10px; border:1px solid #999; border-color: #9C1818; border-collapse:collapse;" width=500 cellpadding=3 cellspacing=0
{| style="background-color:white; font-size:11px; float: right; margin:3px 3px 3px 10px; border:1px solid #999; border-color: #9C1818; border-collapse:collapse;" width=500 cellpadding=3 cellspacing=0
| colspan="2" style="padding:0.3em; background-color:#9C1818; font-size: 18px; color:#FFFFFF" align=center| '''OS2.haupt'''
| colspan="2" style="padding:0.3em; background-color:#9C1818; font-size: 18px; color:#FFFFFF" align=center| '''OS2.haupt'''
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
| '''Dateiname'''
| '''Dateiname'''
| '''OS2.haupt.user.js'''
| '''os2.haupt.user.js'''
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
| '''Version'''
| '''Version'''
| '''0.42 (WebExtensions)'''
| '''0.40'''
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
| '''Autor'''
| '''Autor'''
Zeile 20: Zeile 19:
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
| '''Funktionalität'''
| '''Funktionalität'''
| '''Vorschau für das letzte Spiel: Bilanz'''<br> '''Beschreibungen zu beiden Spielen'''<br> '''Anzeige des Spieltags bzw. der Runde'''<br> '''Benutzermenü für Optionen'''<br> '''Getrennte Option "Liga:" für Erst- und Zweitteam'''<br> '''Erweiterte Optionen auch auf der Seite'''<br> '''Link auf den jeweiligen Spieltag bzw. die jeweilige Runde'''<br> '''Interaktive Menü-Optionen'''<br> '''Gemeinsame Code- und Datenbasis'''<br> '''Gezielte "hl"-Links auf die eigenen Spiele'''
| '''Vorschau für das letzte Spiel: Bilanz'''<br> '''Beschreibungen zu beiden Spielen'''<br> '''Anzeige des Spieltags bzw. der Runde'''<br> '''Benutzermenü für Optionen'''<br> '''Getrennte Option "Liga:" für Erst- und Zweitteam'''<br> '''Erweiterte Optionen auch auf der Seite'''<br> '''Link auf den jeweiligen Spieltag bzw. die jeweilige Runde'''<br> '''Interaktive Menü-Optionen'''<br> '''Gemeinsame Code- und Datenbasis'''
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
| '''Letzte Änderung'''
| '''Letzte Änderung'''
Zeile 26: Zeile 25:
|- bgcolor="#FFCC00"
|- bgcolor="#FFCC00"
|}
|}
== [https://github.com/Eselce/OS2.scripts/blob/master/OS2.haupt.user.js Quellcode] [https://eselce.github.io/OS2.scripts/OS2.haupt.user.js INSTALLATION] ==
<pre>
<pre>
// ==UserScript==
// ==UserScript==
// @name        OS2.haupt
// @name        OS2.haupt
// @namespace    http://os.ongapo.com/
// @namespace    http://os.ongapo.com/
// @version      0.42
// @version      0.40
// @copyright    2016+
// @copyright    2016+
// @author      Sven Loges (SLC)
// @author      Sven Loges (SLC)
// @description  Managerbuero-Abschnitt aus dem Master-Script fuer Online Soccer 2.0
// @description  Managerbuero-Abschnitt aus dem Master-Script fuer Online Soccer 2.0
// @include      /^https?://(www\.)?(os\.ongapo\.com|online-soccer\.eu|os-zeitungen\.com)/haupt\.php(\?changetosecond=\w+(&\w+=?[+\w]+)*)?(#\w+)?$/
// @include      http*://os.ongapo.com/haupt.php
// @grant        GM.getValue
// @include      http*://os.ongapo.com/haupt.php?changetosecond=*
// @grant        GM.setValue
// @include      http*://www.os.ongapo.com/haupt.php
// @grant        GM.deleteValue
// @include      http*://www.os.ongapo.com/haupt.php?changetosecond=*
// @grant        GM.registerMenuCommand
// @include      http*://online-soccer.eu/haupt.php
// @grant        GM.info
// @include      http*://online-soccer.eu/haupt.php?changetosecond=*
// @require     https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// @include      http*://www.online-soccer.eu/haupt.php
// @include     http*://www.online-soccer.eu/haupt.php?changetosecond=*
// @grant        GM_getValue
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_setValue
Zeile 50: Zeile 48:
// ==/UserScript==
// ==/UserScript==


// ECMAScript 6:
// ECMAScript 6: Erlaubt 'const', 'let', ...
/* jshint esnext: true */
/* jshint esnext: true */
/* jshint moz: true */
/* jshint moz: true */
Zeile 100: Zeile 98:
                   'Name'      : "saison",
                   'Name'      : "saison",
                   'Type'      : __OPTTYPES.MC,
                   'Type'      : __OPTTYPES.MC,
                   'ValType'  : 'Number',
                   'ValType'  : "Number",
                   '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 ],
                   'Default'  : 18,
                   'Default'  : 10,
                   'Action'    : __OPTACTION.NXT,
                   'Action'    : __OPTACTION.NXT,
                   'Label'    : "Saison: $",
                   'Label'    : "Saison: $",
Zeile 113: Zeile 111:
                   'Name'      : "ligaSize",
                   'Name'      : "ligaSize",
                   'Type'      : __OPTTYPES.MC,
                   'Type'      : __OPTTYPES.MC,
                   'ValType'  : 'Number',
                   'ValType'  : "Number",
                   'AutoReset' : true,
                   'AutoReset' : true,
                   'Choice'    : [ 10, 18, 20 ],
                   'Choice'    : [ 10, 18, 20 ],
Zeile 124: Zeile 122:
                   'Name'      : "dataZAT",
                   'Name'      : "dataZAT",
                   'Type'      : __OPTTYPES.SD,
                   'Type'      : __OPTTYPES.SD,
                   'ValType'  : 'Number',
                   'ValType'  : "Number",
                   'Hidden'    : true,
                   'Hidden'    : true,
                   'Serial'    : true,
                   'Serial'    : true,
Zeile 144: Zeile 142:
                   'Serial'    : true,
                   'Serial'    : true,
                   'Permanent' : true,
                   'Permanent' : true,
                   'Default'  : undefined,  // new Team() // { 'Team' : undefined, 'Liga' : undefined, 'Land' : undefined, 'TmNr' : 0, 'LdNr' : 0, 'LgNr' : 0 }
                   'Default'  : undefined,  // new Team() // { 'Team' : undefined, 'Liga' : undefined, 'Land' : undefined, 'LdNr' : 0, 'LgNr' : 0 }
                   'Submit'    : undefined,
                   'Submit'    : undefined,
                   'Cols'      : 36,
                   'Cols'      : 36,
Zeile 153: Zeile 151:
               },
               },
     'reset' : {          // Optionen auf die "Werkseinstellungen" zuruecksetzen
     'reset' : {          // Optionen auf die "Werkseinstellungen" zuruecksetzen
                  'FormPrio'  : undefined,
                   'Name'      : "reset",
                   'Name'      : "reset",
                   'Type'      : __OPTTYPES.SI,
                   'Type'      : __OPTTYPES.SI,
Zeile 162: Zeile 159:
               },
               },
     'storage' : {        // Browserspeicher fuer die Klicks auf Optionen
     'storage' : {        // Browserspeicher fuer die Klicks auf Optionen
                  'FormPrio'  : undefined,
                   'Name'      : "storage",
                   'Name'      : "storage",
                   'Type'      : __OPTTYPES.MC,
                   'Type'      : __OPTTYPES.MC,
                   'ValType'  : 'String',
                   'ValType'  : "String",
                   'Choice'    : Object.keys(__OPTMEM),
                   'Choice'    : Object.keys(__OPTMEM),
                   'Action'    : __OPTACTION.NXT,
                   'Action'    : __OPTACTION.NXT,
Zeile 173: Zeile 169:
               },
               },
     'oldStorage' : {      // Vorheriger Browserspeicher fuer die Klicks auf Optionen
     'oldStorage' : {      // Vorheriger Browserspeicher fuer die Klicks auf Optionen
                  'FormPrio'  : undefined,
                   'Name'      : "oldStorage",
                   'Name'      : "oldStorage",
                   'Type'      : __OPTTYPES.SD,
                   'Type'      : __OPTTYPES.SD,
Zeile 181: Zeile 176:
               },
               },
     'showForm' : {        // Optionen auf der Webseite (true = anzeigen, false = nicht anzeigen)
     'showForm' : {        // Optionen auf der Webseite (true = anzeigen, false = nicht anzeigen)
                  'FormPrio'  : 1,
                   'Name'      : "showForm",
                   'Name'      : "showForm",
                   'Type'      : __OPTTYPES.SW,
                   'Type'      : __OPTTYPES.SW,
Zeile 187: Zeile 181:
                   'Permanent' : true,
                   'Permanent' : true,
                   'Default'  : false,
                   'Default'  : false,
                  'Title'    : "$V Optionen",
                   'Action'    : __OPTACTION.NXT,
                   'Action'    : __OPTACTION.NXT,
                   'Label'    : "Optionen anzeigen",
                   'Label'    : "Optionen anzeigen",
                   'Hotkey'    : 'a',
                   'Hotkey'    : 'a',
                  'AltTitle'  : "$V schlie\xDFen",
                   'AltLabel'  : "Optionen verbergen",
                   'AltLabel'  : "Optionen verbergen",
                   'AltHotkey' : 'v',
                   'AltHotkey' : 'v',
Zeile 199: Zeile 191:


// ==================== Invarianter Abschnitt fuer Optionen ====================
// ==================== Invarianter Abschnitt fuer Optionen ====================
// Ein Satz von Logfunktionen, die je nach Loglevel zur Verfuegung stehen. Aufruf: __LOG[level](text)
const __LOG = {
                  'logFun'    : [
                                    console.error,  // [0] Alert
                                    console.error,  // [1] Error
                                    console.log,    // [2] Log: Release
                                    console.log,    // [3] Log: Info
                                    console.log,    // [4] Log: Debug
                                    console.log,    // [5] Log: Verbose
                                    console.log,    // [6] Log: Very verbose
                                    console.log    // [7] Log: Testing
                                ],
                  'init'      : function(win, logLevel = 1) {
                                    for (let level = 0; level < this.logFun.length; level++) {
                                        this[level] = ((level > logLevel) ? function() { } : this.logFun[level]);
                                    }
                                },
                  'stringify' : safeStringify,      // JSON.stringify
                  'changed'  : function(oldVal, newVal) {
                                    const __OLDVAL = this.stringify(oldVal);
                                    const __NEWVAL = this.stringify(newVal);
                                    return ((__OLDVAL !== __NEWVAL) ? __OLDVAL + " => " : "") + __NEWVAL;
                                }
              };
__LOG.init(window, __LOGLEVEL);


// Kompatibilitaetsfunktion zur Ermittlung des Namens einer Funktion (falle <Function>.name nicht vorhanden ist)
// Kompatibilitaetsfunktion zur Ermittlung des Namens einer Funktion (falle <Function>.name nicht vorhanden ist)
Zeile 237: Zeile 201:
}
}


// Ergaenzung fuer Strings: Links oder rechts auffuellen nach Vorlage
// Ein Satz von Logfunktionen, die je nach Loglevel zur Verfuegung stehen. Aufruf: __LOG[level](text)
// padStr: Vorlage, z.B. "00" fuer zweistellige Zahlen
const __LOG = {
// padLeft: true = rechtsbuendig, false = linksbuendig
                  'logFun'  : [
// clip: Abschneiden, falls zu lang
                                  console.error,  // [0] Alert
// return Rechts- oder linksbuendiger String, der so lang ist wie die Vorlage
                                  console.error, // [1] Error
String.prototype.pad = function(padStr, padLeft = true, clip = false) {
                                  console.log,    // [2] Log: Release
    const __LEN = ((clip || (padStr.length > this.length)) ? padStr.length : this.length);
                                  console.log,    // [3] Log: Info
                                  console.log,    // [4] Log: Debug
                                  console.log,   // [5] Log: Verbose
                                  console.log    // [6] Log: Very verbose
                              ],
                  'init'    : function(win, logLevel = 1) {
                                  for (level = 0; level < this.logFun.length; level++) {
                                      this[level] = ((level > logLevel) ? function() { } : this.logFun[level]);
                                  }
                              },
                  'changed'  : function(oldVal, newVal) {
                                  const __OLDVAL = safeStringify(oldVal);
                                  const __NEWVAL = safeStringify(newVal);


    return (padLeft ? String(padStr + this).slice(- __LEN) : String(this + padStr).slice(0, __LEN));
                                  return ((__OLDVAL !== __NEWVAL) ? __OLDVAL + " => " : "") + __NEWVAL;
};
                              }
              };


// Ersetzt in einem String {0}, {1}, ... durch die entsprechenden Parameter
__LOG.init(window, __LOGLEVEL);
// arguments: Parameter, die fuer {0}, {1}, ... eingesetzt werden sollen
// return Resultierender String
String.prototype.format = function() {
    const __ARGS = arguments;
    return this.replace(/{(\d+)}/g, function(match, argIdx) {
                                        const __ARG = __ARGS[argIdx];
                                        return ((__ARG !== undefined) ? __ARG : match);
                                    });
};


// Gibt eine Meldung in der Console aus und oeffnet ein Bestaetigungsfenster mit der Meldung
// Gibt eine Meldung in der Console aus und oeffnet ein Bestaetigungsfenster mit der Meldung
Zeile 263: Zeile 231:
// message: Der Meldungs-Text
// message: Der Meldungs-Text
// data: Ein Wert. Ist er angegeben, wird er in der Console ausgegeben
// data: Ein Wert. Ist er angegeben, wird er in der Console ausgegeben
// return Liefert die Parameter zurueck
function showAlert(label, message, data = undefined) {
function showAlert(label, message, data = undefined) {
     __LOG[0](label + ": " + message);
     __LOG[1](label + ": " + message);


     if (data !== undefined) {
     if (data !== undefined) {
Zeile 272: Zeile 239:


     alert(label + "\n\n" + message);
     alert(label + "\n\n" + message);
    return arguments;
}
// Gibt eine Meldung in der Console aus und oeffnet ein Bestaetigungsfenster
// mit der Meldung zu einer Exception oder einer Fehlermeldung
// label: Eine Ueberschrift
// ex: Exception oder sonstiges Fehlerobjekt
// return Liefert die showAlert()-Parameter zurueck
function showException(label, ex) {
    if (ex && ex.message) {  // Exception
        showAlert(label, ex.message, ex);
    } else {  // sonstiger Fehler
        showAlert(label, ex);
    }
}
// Standard-Callback-Funktion fuer onRejected, also abgefangener Fehler
// in einer Promise bei Exceptions oder Fehler bzw. Rejections
// error: Parameter von reject() im Promise-Objekt, der von Promise.catch() erhalten wurde
// return Liefert die showAlert()-Parameter zurueck
function defaultCatch(error) {
    try {
        const __LABEL = `[${error.lineNumber}] ${__DBMOD.Name}`;
        if (error && error.message) {  // Exception
            return showException(__LABEL, error.message, error);
        } else {
            return showException(__LABEL, error);
        }
    } catch (ex) {
        return showException(`[${ex.lineNumber}] ${__DBMOD.Name}`, ex.message, ex);
    }
}
}


Zeile 338: Zeile 272:


         console.assert((__BASE === null) || ((typeof __BASE) === 'function'), "No function:", __BASE);
         console.assert((__BASE === null) || ((typeof __BASE) === 'function'), "No function:", __BASE);
         console.assert((typeof initFun) === 'function', "Not a function:", initFun);
         console.assert((typeof initFun) === 'function', "No function:", initFun);


         this.init = initFun;
         this.init = initFun;
Zeile 366: Zeile 300:
             const __CREATEPROTO = ((createProto === undefined) ? true : createProto);
             const __CREATEPROTO = ((createProto === undefined) ? true : createProto);


             console.assert((typeof this) === 'function', "Not a function:", this);
             console.assert((typeof this) === 'function');
             console.assert((typeof __MEMBERS) === 'object', "Not an object:", __MEMBERS);
             console.assert((typeof __MEMBERS) === 'object');


             const __CLASS = new Class(this.name || __MEMBERS.__name, baseClass, initFun || __MEMBERS.__init);
             const __CLASS = new Class(this.name || __MEMBERS.__name, baseClass, initFun || __MEMBERS.__init);
Zeile 410: Zeile 344:
                                         return this.className;
                                         return this.className;
                                     }
                                     }
                 });
                 } );


// ==================== Ende Abschnitt fuer Klasse Class ====================
// ==================== Ende Abschnitt fuer Klasse Class ====================
Zeile 457: Zeile 391:
                                     this.home = home;
                                     this.home = home;
                                 }
                                 }
           });
           } );


// ==================== Ende Abschnitt fuer Klasse Delims ====================
// ==================== Ende Abschnitt fuer Klasse Delims ====================
Zeile 536: Zeile 470:
                                     this.node = node;
                                     this.node = node;
                                 }
                                 }
           });
           } );


// ==================== Ende Abschnitt fuer Klasse UriDelims ====================
// ==================== Ende Abschnitt fuer Klasse UriDelims ====================
Zeile 635: Zeile 569:
                                         return __DIRS.slice(1);
                                         return __DIRS.slice(1);
                                     }
                                     }
                 });
                 } );


// ==================== Ende Abschnitt fuer Klasse Path ====================
// ==================== Ende Abschnitt fuer Klasse Path ====================
Zeile 694: Zeile 628:
                                         const __NOSCHEME = this.stripSchemePrefix(path);
                                         const __NOSCHEME = this.stripSchemePrefix(path);
                                         const __INDEXHOST = (__NOSCHEME ? __NOSCHEME.indexOf(__HOSTDELIM) : -1);
                                         const __INDEXHOST = (__NOSCHEME ? __NOSCHEME.indexOf(__HOSTDELIM) : -1);
                                         const __PATH = ((~ __INDEXHOST) ? __NOSCHEME.substring(__INDEXHOST + __HOSTDELIM.length) : __NOSCHEME);
                                         const __PATH = (~ __INDEXHOST) ? __NOSCHEME.substring(__INDEXHOST + __HOSTDELIM.length) : __NOSCHEME;
                                         const __INDEXHOSTPORT = (__PATH ? __PATH.indexOf(__ROOTDELIM) : -1);
                                         const __INDEXHOSTPORT = (__PATH ? __PATH.indexOf(__ROOTDELIM) : -1);
                                         const __HOSTPORT = ((~ __INDEXHOSTPORT) ? __PATH.substring(0, __INDEXHOSTPORT) : undefined);
                                         const __HOSTPORT = (~ __INDEXHOSTPORT) ? __PATH.substring(0, __INDEXHOSTPORT) : undefined;
                                         const __INDEXPORT = (__HOSTPORT ? __HOSTPORT.indexOf(__PORTDELIM) : -1);
                                         const __INDEXPORT = (__HOSTPORT ? __HOSTPORT.indexOf(__PORTDELIM) : -1);
                                         const __HOST = ((~ __INDEXPORT) ? __HOSTPORT.substring(0, __INDEXPORT) : __HOSTPORT);
                                         const __HOST = (~ __INDEXPORT) ? __HOSTPORT.substring(0, __INDEXPORT) : __HOSTPORT;
                                         const __PORT = ((~ __INDEXPORT) ? __HOSTPORT.substring(__INDEXPORT + __PORTDELIM.length) : undefined);
                                         const __PORT = (~ __INDEXPORT) ? __HOSTPORT.substring(__INDEXPORT + __PORTDELIM.length) : undefined;


                                         return {
                                         return {
Zeile 710: Zeile 644:
                                         const __ROOTDELIM = this.delims.root + this.delims.delim;
                                         const __ROOTDELIM = this.delims.root + this.delims.delim;
                                         const __INDEXHOST = (path ? path.indexOf(__HOSTDELIM) : -1);
                                         const __INDEXHOST = (path ? path.indexOf(__HOSTDELIM) : -1);
                                         const __PATH = ((~ __INDEXHOST) ? path.substring(__INDEXHOST + __HOSTDELIM.length) : path);
                                         const __PATH = (~ __INDEXHOST) ? path.substring(__INDEXHOST + __HOSTDELIM.length) : path;
                                         const __INDEXHOSTPORT = (__PATH ? __PATH.indexOf(__ROOTDELIM) : -1);
                                         const __INDEXHOSTPORT = (__PATH ? __PATH.indexOf(__ROOTDELIM) : -1);


                                         return ((~ __INDEXHOSTPORT) ? __PATH.substring(__INDEXHOSTPORT) : __PATH);
                                         return (~ __INDEXHOSTPORT) ? __PATH.substring(__INDEXHOSTPORT) : __PATH;
                                     },
                                     },
               'getSchemePrefix'  : function(path = undefined) {
               'getSchemePrefix'  : function(path = undefined) {
Zeile 719: Zeile 653:
                                         const __INDEXSCHEME = (path ? path.indexOf(__SCHEMEDELIM) : -1);
                                         const __INDEXSCHEME = (path ? path.indexOf(__SCHEMEDELIM) : -1);


                                         return ((~ __INDEXSCHEME) ? path.substring(0, __INDEXSCHEME) : undefined);
                                         return (~ __INDEXSCHEME) ? path.substring(0, __INDEXSCHEME) : undefined;
                                     },
                                     },
               'stripSchemePrefix' : function(path = undefined) {
               'stripSchemePrefix' : function(path = undefined) {
Zeile 725: Zeile 659:
                                         const __INDEXSCHEME = (path ? path.indexOf(__SCHEMEDELIM) : -1);
                                         const __INDEXSCHEME = (path ? path.indexOf(__SCHEMEDELIM) : -1);


                                         return ((~ __INDEXSCHEME) ? path.substring(__INDEXSCHEME + __INDEXSCHEME.length) : path);
                                         return (~ __INDEXSCHEME) ? path.substring(__INDEXSCHEME + __INDEXSCHEME.length) : path;
                                     },
                                     },
               'getNodeSuffix'    : function(path = undefined) {
               'getNodeSuffix'    : function(path = undefined) {
Zeile 731: Zeile 665:
                                         const __INDEXNODE = (path ? path.lastIndexOf(__NODEDELIM) : -1);
                                         const __INDEXNODE = (path ? path.lastIndexOf(__NODEDELIM) : -1);


                                         return ((~ __INDEXNODE) ? path.substring(__INDEXNODE + __NODEDELIM.length) : undefined);
                                         return (~ __INDEXNODE) ? path.substring(__INDEXNODE + __NODEDELIM.length) : undefined;
                                     },
                                     },
               'stripNodeSuffix'  : function(path = undefined) {
               'stripNodeSuffix'  : function(path = undefined) {
Zeile 737: Zeile 671:
                                         const __INDEXNODE = (path ? path.lastIndexOf(__NODEDELIM) : -1);
                                         const __INDEXNODE = (path ? path.lastIndexOf(__NODEDELIM) : -1);


                                         return ((~ __INDEXNODE) ? path.substring(0, __INDEXNODE) : path);
                                         return (~ __INDEXNODE) ? path.substring(0, __INDEXNODE) : path;
                                     },
                                     },
               'getQueryString'    : function(path = undefined) {
               'getQueryString'    : function(path = undefined) {
Zeile 744: Zeile 678:
                                         const __INDEXQUERY = (__PATH ? __PATH.indexOf(__QUERYDELIM) : -1);
                                         const __INDEXQUERY = (__PATH ? __PATH.indexOf(__QUERYDELIM) : -1);


                                         return ((~ __INDEXQUERY) ? __PATH.substring(__INDEXQUERY + __QUERYDELIM.length) : undefined);
                                         return (~ __INDEXQUERY) ? __PATH.substring(__INDEXQUERY + __QUERYDELIM.length) : undefined;
                                     },
                                     },
               'stripQueryString'  : function(path = undefined) {
               'stripQueryString'  : function(path = undefined) {
Zeile 750: Zeile 684:
                                         const __INDEXQUERY = (path ? path.indexOf(__QUERYDELIM) : -1);
                                         const __INDEXQUERY = (path ? path.indexOf(__QUERYDELIM) : -1);


                                         return ((~ __INDEXQUERY) ? path.substring(0, __INDEXQUERY) : path);
                                         return (~ __INDEXQUERY) ? path.substring(0, __INDEXQUERY) : path;
                                     },
                                     },
               'formatParams'      : function(params, formatFun, delim = ' ', assign = '=') {
               'formatParams'      : function(params, formatFun, delim = ' ', assign = '=') {
Zeile 772: Zeile 706:
                                                 if (__PARAM) {
                                                 if (__PARAM) {
                                                     const __INDEX = __PARAM.indexOf(assign);
                                                     const __INDEX = __PARAM.indexOf(assign);
                                                     const __KEY = ((~ __INDEX) ? __PARAM.substring(0, __INDEX) : __PARAM);
                                                     const __KEY = (~ __INDEX) ? __PARAM.substring(0, __INDEX) : __PARAM;
                                                     const __VAL = ((~ __INDEX) ? parseFun(__PARAM.substring(__INDEX + assign.length)) : true);
                                                     const __VAL = (~ __INDEX) ? parseFun(__PARAM.substring(__INDEX + assign.length)) : true;


                                                     __RET[__KEY] = __VAL;
                                                     __RET[__KEY] = __VAL;
Zeile 793: Zeile 727:
                                             const __LOWER = (value ? value.toLowerCase() : undefined);
                                             const __LOWER = (value ? value.toLowerCase() : undefined);


                                             if ((__LOWER === 'true') || (__LOWER === 'false')) {
                                             if ((__LOWER === "true") || (__LOWER === "false")) {
                                                 return (value === 'true');
                                                 return (value === "true");
                                             }
                                             }
                                         }
                                         }
Zeile 846: Zeile 780:
                                         return Path.prototype.getDirs.call(this, __PATH);
                                         return Path.prototype.getDirs.call(this, __PATH);
                                     }
                                     }
           });
           } );


// ==================== Ende Abschnitt fuer Klasse URI ====================
// ==================== Ende Abschnitt fuer Klasse URI ====================
Zeile 886: Zeile 820:
                                   return this.getPath();
                                   return this.getPath();
                               }
                               }
                 });
                 } );


// ==================== Ende Abschnitt fuer Klasse Directory ====================
// ==================== Ende Abschnitt fuer Klasse Directory ====================
Zeile 914: Zeile 848:
                                     return ret;
                                     return ret;
                                 }
                                 }
                 });
                 } );


// ==================== Ende Abschnitt fuer Klasse ObjRef ====================
// ==================== Ende Abschnitt fuer Klasse ObjRef ====================
Zeile 959: Zeile 893:


// Gibt ein Produkt zurueck. Ist einer der Multiplikanten nicht definiert, wird ein Alternativwert geliefert
// Gibt ein Produkt zurueck. Ist einer der Multiplikanten nicht definiert, wird ein Alternativwert geliefert
// valueA: Ein Multiplikant. Ist dieser undefined, wird als Produkt defValue zurueckgeliefert
// valueA: Ein Multipliksnt. Ist dieser undefined, wird als Produkt defValue zurueckgeliefert
// valueB: Ein Multiplikant. Ist dieser undefined, wird als Produkt defValue zurueckgeliefert
// valueB: Ein Multipliksnt. Ist dieser undefined, wird als Produkt defValue zurueckgeliefert
// digits: Anzahl der Stellen nach dem Komma fuer das Produkt (Default: 0)
// digits: Anzahl der Stellen nach dem Komma fuer das Produkt (Default: 0)
// defValue: Default-Wert fuer den Fall, dass ein Multiplikant nicht gesetzt ist (Default: NaN)
// defValue: Default-Wert fuer den Fall, dass ein Multiplikant nicht gesetzt ist (Default: NaN)
Zeile 969: Zeile 903:
     if ((valueA !== undefined) && (valueB !== undefined)) {
     if ((valueA !== undefined) && (valueB !== undefined)) {
         product = parseFloat(valueA) * parseFloat(valueB);
         product = parseFloat(valueA) * parseFloat(valueB);
    }
    if (isNaN(product)) {
        product = defValue;
     }
     }


Zeile 978: Zeile 908:
}
}


// Gibt eine Ordinalzahl zur uebergebenen Zahl zurueck
// Ueberprueft, ob ein Objekt einer bestimmten Klasse angehoert (ggfs. per Vererbung)
// value: Eine ganze Zahl
// defValue: Default-Wert fuer den Fall, dass der Wert nicht gesetzt ist (Default: '*')
// return Die Ordinalzahl als String der Form "n." oder defValue, falls nicht angegeben
function getOrdinal(value, defValue = '*') {
    return getValue(value, defValue, value + '.');
}
 
// Hilfsfunktion fuer Array.sort(): Vergleich zweier Zahlen
// valueA: Erster Zahlenwert
// valueB: Zweiter Zahlenwert
// return -1 = kleiner, 0 = gleich, +1 = groesser
function compareNumber(valueA, valueB) {
    return +(valueA > valueB) || (+(valueA === valueB) - 1);
}
 
// Ueberprueft, ob ein Objekt einer bestimmten Klasse angehoert (ggfs. per Vererbung)
// obj: Ein (generisches) Objekt
// obj: Ein (generisches) Objekt
// base: Eine Objektklasse (Konstruktor-Funktion)
// base: Eine Objektklasse (Konstruktor-Funktion)
Zeile 1.000: Zeile 914:
function instanceOf(obj, base) {
function instanceOf(obj, base) {
     while (obj !== null) {
     while (obj !== null) {
         if (obj === base.prototype) {
         if (obj === base.prototype)
             return true;
             return true;
        }
         if ((typeof obj) === 'xml') {  // Sonderfall mit Selbstbezug
         if ((typeof obj) === 'xml') {  // Sonderfall mit Selbstbezug
             return (base.prototype === XML.prototype);
             return (base.prototype === XML.prototype);
Zeile 1.052: Zeile 965:
     let active = true;
     let active = true;


     if (inList) {
     if (inList !== undefined) {
         active = (inList[item] === true);  // gesetzt und true
         active = (inList[item] === true);  // gesetzt und true
     }
     }
     if (exList) {
     if (exList !== undefined) {
         if (exList[item] === true) {  // gesetzt und true
         if (exList[item] === true) {  // gesetzt und true
             active = false;  // NICHT anzeigen
             active = false;  // NICHT anzeigen
Zeile 1.074: Zeile 987:
         if (checkItem(item, addList, ignList)) {
         if (checkItem(item, addList, ignList)) {
             data[item] = addData[item];
             data[item] = addData[item];
        }
    }
    return data;
}
// Entfernt Properties in einem Objekt
// data: Objekt, deren Properties bearbeitet werden
// delList: Checkliste der zu loeschenden Items (true fuer loeschen), falls angegeben
// ignList: Checkliste der ignorierten Items (true fuer auslassen), falls angegeben
// return Das veraenderte Objekt ohne die geloeschten Properties
function delProps(data, delList = undefined, ignList = undefined) {
    for (let item in getValue(data, { })) {
        if (checkItem(item, delList, ignList)) {
            delete data[item];
         }
         }
     }
     }
Zeile 1.170: Zeile 1.068:
}
}


// Replacer fuer JSON.stringify() oder safeStringify(), der Arrays kompakter darstellt
// Speichert einen beliebiegen (strukturierten) Wert unter einem Namen ab
// key: Der uebergebene Schluessel
// name: GM_setValue-Name, unter dem die Daten gespeichert werden
// value: Der uebergebene Wert
// value: Beliebiger (strukturierter) Wert
// return Fuer Arrays eine kompakte Darstellung, sonst derselbe Wert
// return String-Darstellung des Wertes
function replaceArraySimple(key, value) {
function serialize(name, value) {
     if (Array.isArray(value)) {
     const __STREAM = (value !== undefined) ? safeStringify(value) : value;
        return "[ " + value.join(", ") + " ]";
    }


     return value;
     __LOG[4](name + " >> " + __STREAM);
}


// Replacer fuer JSON.stringify() oder safeStringify(), der Arrays kompakter darstellt
     GM_setValue(name, __STREAM);
// key: Der uebergebene Schluessel
// value: Der uebergebene Wert
// return Fuer Arrays eine kompakte Darstellung, sonst derselbe Wert
function replaceArray(key, value) {
     if (Array.isArray(value)) {
        __RET = value.map(function(element) {
                              return safeStringify(element, replaceArray, 0);
                          });


        return __RET;
     return __STREAM;
    }
 
     return value;
}
}


// Moegliche einfache Ersetzungen mit '$'...
// Holt einen beliebiegen (strukturierter) Wert unter einem Namen zurueck
let textSubst;
// name: GM_setValue-Name, unter dem die Daten gespeichert werden
// defValue: Default-Wert fuer den Fall, dass nichts gespeichert ist
// return Objekt, das unter dem Namen gespeichert war
function deserialize(name, defValue = undefined) {
    const __STREAM = GM_getValue(name, defValue);


// Substituiert '$'-Parameter in einem Text
     __LOG[4](name + " << " + __STREAM);
// text: Urspruenglicher Text mit '$'-Befehlen
// par1: Der (erste) uebergebene Parameter
// return Fuer Arrays eine kompakte Darstellung, sonst derselbe Wert
function substParam(text, par1) {
     let ret = getValue(text, "");


     if (! textSubst) {
     if ((__STREAM !== undefined) && __STREAM.length) {
         textSubst  = {
         try {
                'n' : __DBMOD.name,
            return JSON.parse(__STREAM);
                'v' : __DBMOD.version,
        } catch (ex) {
                'V' : __DBMOD.Name
            __LOG[1](name + ": " + ex.message);
            };
        }
     }
     }


     for (let ch in textSubst) {
     return undefined;
        const __SUBST = textSubst[ch];
}


         ret = ret.replace('$' + ch, __SUBST);
// Setzt eine Option dauerhaft und laedt die Seite neu
// name: Name der Option als Speicherort
// value: Zu setzender Wert
// reload: Seite mit neuem Wert neu laden
// return Gespeicherter Wert fuer setOptValue()
function setStored(name, value, reload = false, serial = false) {
    if (serial) {
        serialize(name, value);
    } else {
         GM_setValue(name, value);
     }
     }


    return ret.replace('$', par1);
     if (reload) {
}
         window.location.reload();
 
// Fuegt in die uebergebene Zahl Tausender-Trennpunkte ein
// Wandelt einen etwaig vorhandenen Dezimalpunkt in ein Komma um
// numberString: Dezimalzahl als String
// return Diese Dezimalzahl als String mit Tausender-Trennpunkten und Komma statt Dezimalpunkt
function getNumberString(numberString) {
     if (numberString.lastIndexOf('.') !== -1) {
        // Zahl enthaelt Dezimalpunkt
        const __VORKOMMA = numberString.substring(0, numberString.lastIndexOf('.'));
        const __NACHKOMMA = numberString.substring(numberString.lastIndexOf('.') + 1, numberString.length);
 
        return getNumberString(__VORKOMMA) + ',' + __NACHKOMMA;
    } else {
         // Kein Dezimalpunkt, fuege Tausender-Trennpunkte ein:
        // String umdrehen, nach jedem dritten Zeichen Punkt einfuegen, dann wieder umdrehen:
        const __TEMP = reverseString(numberString);
        let result = "";
 
        for (let i = 0; i < __TEMP.length; i++) {
            if ((i > 0) && (i % 3 === 0)) {
                result += '.';
            }
            result += __TEMP.substr(i, 1);
        }
 
        return reverseString(result);
     }
     }
}


// Dreht den uebergebenen String um
     return value;
// string: Eine Zeichenkette
// return Dieselbe Zeichenkette rueckwaerts
function reverseString(string) {
    let result = "";
 
    for (let i = string.length - 1; i >= 0; i--) {
        result += string.substr(i, 1);
    }
 
     return result;
}
}


// Speichert einen String/Integer/Boolean-Wert unter einem Namen ab
// Setzt den naechsten Wert aus einer Array-Liste als Option
// name: GM.setValue()-Name, unter dem die Daten gespeichert werden
// arr: Array-Liste mit den moeglichen Optionen
// value: Zu speichernder String/Integer/Boolean-Wert
// name: Name der Option als Speicherort
// return Promise auf ein Objekt, das 'name' und 'value' der Operation enthaelt
// value: Vorher gesetzter Wert
function storeValue(name, value) {
// reload: Seite mit neuem Wert neu laden
    __LOG[4](name + " >> " + value);
// return Gespeicherter Wert fuer setOptValue()
 
function setNextStored(arr, name, value, reload = false, serial = false) {
     return GM.setValue(name, value).then(voidValue => {
     return setStored(name, getNextValue(arr, value), reload, serial);
            __LOG[5]("OK " + name + " >> " + value);
 
            return Promise.resolve({
                    'name'  : name,
                    'value' : value
                });
        }, defaultCatch);
}
}


// Holt einen String/Integer/Boolean-Wert unter einem Namen zurueck
// Fuehrt die in einem Storage gespeicherte Operation aus
// name: GM.getValue()-Name, unter dem die Daten gespeichert wurden
// memory: __OPTMEM.normal = unbegrenzt gespeichert (localStorage), __OPTMEM.begrenzt = bis Browserende gespeichert (sessionStorage), __OPTMEM.inaktiv
// defValue: Default-Wert fuer den Fall, dass nichts gespeichert ist
// return Array von Objekten mit 'cmd' / 'key' / 'val' (derzeit maximal ein Kommando) oder undefined
// return Promise fuer den String/Integer/Boolean-Wert, der unter dem Namen gespeichert war
function getStoredCmds(memory = undefined) {
function summonValue(name, defValue = undefined) {
     const __STORAGE = getMemory(memory);
     return GM.getValue(name, defValue).then(value => {
    const __MEMORY = __STORAGE.Value;
            __LOG[4](name + " << " + value);
    const __RUNPREFIX = __STORAGE.Prefix;
    const __STOREDCMDS = [];


            return Promise.resolve(value);
    if (__MEMORY !== undefined) {
         }, ex => {
         const __GETITEM = function(item) {
            __LOG[0](name + ": " + ex.message);
                              return __MEMORY.getItem(__RUNPREFIX + item);
 
                          };
            return Promise.reject(ex);
        const __DELITEM = function(item) {
         }, defaultCatch);
                              return __MEMORY.removeItem(__RUNPREFIX + item);
}
                          };
         const __CMD = ((__MEMORY !== undefined) ? __GETITEM('cmd') : undefined);


// Speichert einen beliebiegen (strukturierten) Wert unter einem Namen ab
        if (__CMD !== undefined) {
// name: GM.setValue()-Name, unter dem die Daten gespeichert werden
            const __KEY = __GETITEM('key');
// value: Beliebiger (strukturierter) Wert
            let value = __GETITEM('val');
// return Promise auf ein Objekt, das 'name' und 'value' in der String-Darstellung des Wertes enthaelt
function serialize(name, value) {
    const __STREAM = ((value !== undefined) ? safeStringify(value) : value);


    return storeValue(name, __STREAM);
            try {
}
                value = JSON.parse(value);
            } catch (ex) {
                __LOG[1]("getStoredCmds(): " + __CMD + " '" + __KEY + "' hat illegalen Wert '" + value + "'");
                // ... meist kann man den String selber aber speichern, daher kein "return"...
            }


// Holt einen beliebiegen (strukturierter) Wert unter einem Namen zurueck
            __STOREDCMDS.push({
// name: GM.getValue()-Name, unter dem die Daten gespeichert wurden
                                'cmd' : __CMD,
// defValue: Default-Wert fuer den Fall, dass nichts gespeichert ist
                                'key' : __KEY,
// return Promise fuer das Objekt, das unter dem Namen gespeichert war
                                'val' : value
function deserialize(name, defValue = undefined) {
                            });
    return summonValue(name).then(stream => {
         }
            if (stream && stream.length) {
                return JSON.parse(stream);
            } else {
                return defValue;
            }
         });
}


// Setzt die Seite gemaess der Aenderungen zurueck...
        __DELITEM('cmd');
// reload: Seite wird ganz neu geladen
         __DELITEM('key');
function refreshPage(reload = true) {
         __DELITEM('val');
    if (reload) {
         __LOG[2]("Seite wird neu geladen...");
         window.location.reload();
     }
     }
}
 
 
     return (__STOREDCMDS.length ? __STOREDCMDS : undefined);
// Setzt eine Option dauerhaft und laedt die Seite neu
// name: Name der Option als Speicherort
// value: Zu setzender Wert
// reload: Seite mit neuem Wert neu laden
// serial: Serialization fuer komplexe Daten
// onFulfilled: Reaktion auf Speicherung im resolve-Fall (1. Promise.then()-Parameter)
// onRejected: Reaktion auf Speicherung im reject-Fall (2. Promise.then()-Parameter)
// return Gespeicherter Wert fuer setOptValue()
function setStored(name, value, reload = false, serial = false, onFulfilled = undefined, onRejected = undefined) {
    (serial ? serialize(name, value)
            : storeValue(name, value))
                .then(onFulfilled, onRejected)
                .then(() => refreshPage(reload), defaultCatch);  // Ende der Kette...
 
     return value;
}
 
// Setzt den naechsten Wert aus einer Array-Liste als Option
// arr: Array-Liste mit den moeglichen Optionen
// name: Name der Option als Speicherort
// value: Vorher gesetzter Wert
// reload: Seite mit neuem Wert neu laden
// serial: Serialization fuer komplexe Daten
// onFulfilled: Reaktion auf Speicherung im resolve-Fall (1. Promise.then()-Parameter)
// onRejected: Reaktion auf Speicherung im reject-Fall (2. Promise.then()-Parameter)
// return Gespeicherter Wert fuer setOptValue()
function setNextStored(arr, name, value, reload = false, serial = false, onFulfilled = undefined, onRejected = undefined) {
    return setStored(name, getNextValue(arr, value), reload, serial, onFulfilled, onRejected);
}
}


// Fuehrt die in einem Storage gespeicherte Operation aus
// Fuehrt die in einem Storage gespeicherte Operation aus
// storedCmds: Array von Objekten mit 'cmd' / 'key' / 'val' (siehe getStoredCmds())
// optSet: Set mit den Optionen
// beforeLoad: Angabe, ob nach der Speicherung noch loadOptions() aufgerufen wird
// memory: __OPTMEM.normal = unbegrenzt gespeichert (localStorage), __OPTMEM.begrenzt = bis Browserende gespeichert (sessionStorage), __OPTMEM.inaktiv
// memory: __OPTMEM.normal = unbegrenzt gespeichert (localStorage), __OPTMEM.begrenzt = bis Browserende gespeichert (sessionStorage), __OPTMEM.inaktiv
// return Array von Objekten mit 'cmd' / 'key' / 'val' (derzeit maximal ein Kommando) oder undefined
// return Array von Operationen (wie storedCmds), die fuer die naechste Phase uebrig bleiben
function getStoredCmds(memory = undefined) {
function runStoredCmds(storedCmds, optSet = undefined, beforeLoad = undefined) {
     const __STORAGE = getMemory(memory);
     const __BEFORELOAD = getValue(beforeLoad, true);
     const __MEMORY = __STORAGE.Value;
     const __STOREDCMDS = getValue(storedCmds, []);
     const __RUNPREFIX = __STORAGE.Prefix;
     const __LOADEDCMDS = [];
     const __STOREDCMDS = [];
     let invalidated = false;


     if (__MEMORY !== undefined) {
     while (__STOREDCMDS.length) {
         const __GETITEM = function(item) {
         const __STORED = __STOREDCMDS.shift();
                              return __MEMORY.getItem(__RUNPREFIX + item);
        const __CMD = __STORED.cmd;
                          };
         const __KEY = __STORED.key;
         const __DELITEM = function(item) {
         const __VAL = __STORED.val;
                              return __MEMORY.removeItem(__RUNPREFIX + item);
                          };
         const __CMD = ((__MEMORY !== undefined) ? __GETITEM('cmd') : undefined);


         if (__CMD !== undefined) {
         if (__BEFORELOAD) {
             const __KEY = __GETITEM('key');
             if (__STOREDCMDS.length) {
            let value = __GETITEM('val');
                invalidateOpts(optSet); // alle Optionen invalidieren
 
                 invalidated = true;
            try {
             }
                 value = JSON.parse(value);
            switch (__OPTACTION[__CMD]) {
             } catch (ex) {
            case __OPTACTION.SET : __LOG[4]("SET '" + __KEY + "' " + __VAL);
                __LOG[0]("getStoredCmds(): " + __CMD + " '" + __KEY + "' hat illegalen Wert '" + value + "'");
                                  setStored(__KEY, __VAL, false, false);
                // ... meist kann man den String selber aber speichern, daher kein "return"...
                                  break;
            case __OPTACTION.NXT : __LOG[4]("SETNEXT '" + __KEY + "' " + __VAL);
                                  //setNextStored(__CONFIG.Choice, __KEY, __VAL, false, false);
                                  setStored(__KEY, __VAL, false, false);
                                  break;
            case __OPTACTION.RST : __LOG[4]("RESET (delayed)");
                                  __LOADEDCMDS.push(__STORED);
                                  break;
            default :              break;
             }
             }
 
         } else {
            __STOREDCMDS.push({
                                'cmd' : __CMD,
                                'key' : __KEY,
                                'val' : value
                            });
        }
 
        __DELITEM('cmd');
        __DELITEM('key');
        __DELITEM('val');
    }
 
    return (__STOREDCMDS.length ? __STOREDCMDS : undefined);
}
 
// Fuehrt die in einem Storage gespeicherte Operation aus
// storedCmds: Array von Objekten mit 'cmd' / 'key' / 'val' (siehe getStoredCmds())
// optSet: Object mit den Optionen
// beforeLoad: Angabe, ob nach der Speicherung noch loadOptions() aufgerufen wird
// onFulfilled: Reaktion auf Speicherung im resolve-Fall (1. Promise.then()-Parameter)
// onRejected: Reaktion auf Speicherung im reject-Fall (2. Promise.then()-Parameter)
// return Promise auf ein Array von Operationen (wie storedCmds), die fuer die naechste Phase uebrig bleiben
async function runStoredCmds(storedCmds, optSet = undefined, beforeLoad = undefined, onFulfilled = undefined, onRejected = undefined) {
    const __BEFORELOAD = getValue(beforeLoad, true);
    const __STOREDCMDS = getValue(storedCmds, []);
    const __LOADEDCMDS = [];
    let invalidated = false;
 
    while (__STOREDCMDS.length) {
        const __STORED = __STOREDCMDS.shift();
        const __CMD = __STORED.cmd;
        const __KEY = __STORED.key;
        const __VAL = __STORED.val;
 
        if (__BEFORELOAD) {
            if (__STOREDCMDS.length) {
                await invalidateOpts(optSet);  // alle Optionen invalidieren
                invalidated = true;
            }
            switch (__OPTACTION[__CMD]) {
            case __OPTACTION.SET : __LOG[4]("SET '" + __KEY + "' " + __VAL);
                                  setStored(__KEY, __VAL, false, false, onFulfilled, onRejected);
                                  break;
            case __OPTACTION.NXT : __LOG[4]("SETNEXT '" + __KEY + "' " + __VAL);
                                  //setNextStored(__CONFIG.Choice, __KEY, __VAL, false, false, onFulfilled, onRejected);
                                  setStored(__KEY, __VAL, false, false, onFulfilled, onRejected);
                                  break;
            case __OPTACTION.RST : __LOG[4]("RESET (delayed)");
                                  __LOADEDCMDS.push(__STORED);
                                  break;
            default :              break;
            }
         } else {
             switch (__OPTACTION[__CMD]) {
             switch (__OPTACTION[__CMD]) {
             case __OPTACTION.SET :
             case __OPTACTION.SET :
Zeile 1.449: Zeile 1.217:
                                   break;
                                   break;
             case __OPTACTION.RST : __LOG[4]("RESET");
             case __OPTACTION.RST : __LOG[4]("RESET");
                                   await resetOptions(optSet, false);
                                   resetOptions(optSet, false);
                                   await loadOptions(optSet);  // Reset auf umbenannte Optionen anwenden!
                                   loadOptions(optSet);  // Reset auf umbenannte Optionen anwenden!
                                   break;
                                   break;
             default :              break;
             default :              break;
Zeile 1.552: Zeile 1.320:
// force: Laedt auch Optionen mit 'AutoReset'-Attribut
// force: Laedt auch Optionen mit 'AutoReset'-Attribut
// return Gesetzter Wert
// return Gesetzter Wert
function getOptValue(opt, defValue = undefined, load = true, asyncLoad = false, force = false) {
function getOptValue(opt, defValue = undefined, load = true, force = false) {
     let value;
     let value;


     if (opt !== undefined) {
     if (opt !== undefined) {
         if (load && ! opt.Loaded) {
         if (load && ! opt.Loaded) {
             if (! opt.Promise) {
             value = loadOption(opt, force);
                loadOption(opt, force);
            }
            if (! asyncLoad) {
                __LOG[0]("Warnung: getOptValue(" + getOptName(opt) + ") fordert zum Nachladen auf, daher nur Default-Wert!");
            }
         } else {
         } else {
             value = opt.Value;
             value = opt.Value;
Zeile 1.652: Zeile 1.415:
// Gibt rekursiv und detailliert die Groesse des benutzten Speichers fuer ein Objekt aus
// Gibt rekursiv und detailliert die Groesse des benutzten Speichers fuer ein Objekt aus
// value: (Enumerierbares) Objekt oder Wert, dessen Groesse gemessen wird
// value: (Enumerierbares) Objekt oder Wert, dessen Groesse gemessen wird
// out: Logfunktion, etwa __LOG[4]
// out: Logfunktion, etwa console.log
// depth: Gewuenschte Rekursionstiefe (0 = nur dieses Objekt, -1 = alle Ebenen)
// depth: Gewuenschte Rekursionstiefe (0 = nur dieses Objekt, -1 = alle Ebenen)
// name: Name des Objekts
// name: Name des Objekts
Zeile 1.661: Zeile 1.424:
         const __SIZE = value.length;
         const __SIZE = value.length;


         __OUT("USAGE: " + name + '\t' + __SIZE + '\t' + value.slice(0, 255));
         __OUT("USAGE: " + name + '\t' + __SIZE + '\t' + value.substr(0, 255));
     } else if ((typeof value) === 'object') {
     } else if ((typeof value) === 'object') {
         if (depth === 0) {
         if (depth === 0) {
Zeile 1.683: Zeile 1.446:
// Restauriert den vorherigen Speicher (der in einer Option definiert ist)
// Restauriert den vorherigen Speicher (der in einer Option definiert ist)
// opt: Option zur Wahl des Speichers
// opt: Option zur Wahl des Speichers
// return Promise auf gesuchten Speicher oder Null-Speicher ('inaktiv')
// return Gesuchter Speicher oder Null-Speicher ('inaktiv')
async function restoreMemoryByOpt(opt) {
function restoreMemoryByOpt(opt) {
     // Memory Storage fuer vorherige Speicherung...
     // Memory Storage fuer vorherige Speicherung...
     const __STORAGE = await getOptValue(opt, __MEMNORMAL, true, true, true);
     const __STORAGE = getOptValue(opt, __MEMNORMAL, true, true);


     return __OPTMEM[__STORAGE];
     return __OPTMEM[__STORAGE];
Zeile 1.694: Zeile 1.457:
// opt: Option zur Wahl des Speichers
// opt: Option zur Wahl des Speichers
// saveOpt: Option zur Speicherung der Wahl des Speichers (fuer restoreMemoryByOpt)
// saveOpt: Option zur Speicherung der Wahl des Speichers (fuer restoreMemoryByOpt)
// onFulfilled: Reaktion auf Speicherung im resolve-Fall (1. Promise.then()-Parameter)
// onRejected: Reaktion auf Speicherung im reject-Fall (2. Promise.then()-Parameter)
// return Gesuchter Speicher oder Null-Speicher ('inaktiv'), falls speichern nicht moeglich ist
// return Gesuchter Speicher oder Null-Speicher ('inaktiv'), falls speichern nicht moeglich ist
function startMemoryByOpt(opt, saveOpt = undefined, onFulfilled = undefined, onRejected = undefined) {
function startMemoryByOpt(opt, saveOpt = undefined) {
     // Memory Storage fuer naechste Speicherung...
     // Memory Storage fuer naechste Speicherung...
     let storage = getOptValue(opt, __MEMNORMAL);
     let storage = getOptValue(opt, __MEMNORMAL);
Zeile 1.710: Zeile 1.471:


     if (saveOpt !== undefined) {
     if (saveOpt !== undefined) {
         setOpt(saveOpt, storage, false, onFulfilled, onRejected);
         setOpt(saveOpt, storage, false);
     }
     }


Zeile 1.721: Zeile 1.482:


// Initialisiert das Script-Modul und ermittelt die beschreibenden Daten
// Initialisiert das Script-Modul und ermittelt die beschreibenden Daten
// meta: Metadaten des Scripts (Default: GM.info.script)
// meta: Metadaten des Scripts (Default: GM_info.script)
// return Beschreibende Daten fuer __DBMOD
// return Beschreibende Daten fuer __DBMOD
function ScriptModule(meta) {
function ScriptModule(meta) {
     'use strict';
     'use strict';


     const __META = getValue(meta, GM.info.script);
     const __META = getValue(meta, GM_info.script);
     const __PROPS = {
     const __PROPS = {
                 'name'        : true,
                 'name'        : true,
Zeile 1.832: Zeile 1.593:
// funOff: Funktion zum Ausschalten
// funOff: Funktion zum Ausschalten
// keyOff: Hotkey zum Ausschalten im Menu
// keyOff: Hotkey zum Ausschalten im Menu
// return Promise von GM.registerMenuCommand()
function registerMenuOption(val, menuOn, funOn, keyOn, menuOff, funOff, keyOff) {
function registerMenuOption(val, menuOn, funOn, keyOn, menuOff, funOff, keyOff) {
     const __ON  = (val ? '*' : "");
     const __ON  = (val ? '*' : "");
Zeile 1.840: Zeile 1.600:


     if (val) {
     if (val) {
         return GM.registerMenuCommand(menuOff, funOff, keyOff).then(result => menuOn);
         GM_registerMenuCommand(menuOff, funOff, keyOff);
     } else {
     } else {
         return GM.registerMenuCommand(menuOn, funOn, keyOn).then(result => menuOff);
         GM_registerMenuCommand(menuOn, funOn, keyOn);
     }
     }
}
}
Zeile 1.852: Zeile 1.612:
// fun: Funktion zum Setzen des naechsten Wertes
// fun: Funktion zum Setzen des naechsten Wertes
// key: Hotkey zum Setzen des naechsten Wertes im Menu
// key: Hotkey zum Setzen des naechsten Wertes im Menu
// return Promise von GM.registerMenuCommand()
function registerNextMenuOption(val, arr, menu, fun, key) {
function registerNextMenuOption(val, arr, menu, fun, key) {
     const __MENU = substParam(menu, val);
     const __MENU = menu.replace('$', val);
     let options = "OPTION " + __MENU;
     let options = "OPTION " + __MENU;


Zeile 1.866: Zeile 1.625:
     __LOG[3](options);
     __LOG[3](options);


     return GM.registerMenuCommand(__MENU, fun, key).then(result => __MENU);
     GM_registerMenuCommand(__MENU, fun, key);
}
}


Zeile 1.876: Zeile 1.635:
// hidden: Angabe, ob Menupunkt nicht sichtbar sein soll (Default: sichtbar)
// hidden: Angabe, ob Menupunkt nicht sichtbar sein soll (Default: sichtbar)
// serial: Serialization fuer komplexe Daten
// serial: Serialization fuer komplexe Daten
// return Promise von GM.registerMenuCommand() (oder String-Version des Wertes)
function registerDataOption(val, menu, fun, key, hidden = false, serial = true) {
function registerDataOption(val, menu, fun, key, hidden = false, serial = true) {
     const __VALUE = ((serial && (val !== undefined)) ? safeStringify(val) : val);
     const __VALUE = ((serial && (val !== undefined)) ? safeStringify(val) : val);
     const __MENU = substParam(menu, __VALUE);
     const __MENU = getValue(menu, "").replace('$', __VALUE);
     const __OPTIONS = (hidden ? "HIDDEN " : "") + "OPTION " + __MENU +
     const __OPTIONS = (hidden ? "HIDDEN " : "") + "OPTION " + __MENU +
                       getValue(__VALUE, "", " = " + __VALUE);
                       getValue(__VALUE, "", " = " + __VALUE);
Zeile 1.885: Zeile 1.643:
     __LOG[hidden ? 4 : 3](__OPTIONS);
     __LOG[hidden ? 4 : 3](__OPTIONS);


     if (hidden) {
     if (! hidden) {
         return Promise.resolve(__VALUE);
         GM_registerMenuCommand(__MENU, fun, key);
    } else {
        return GM.registerMenuCommand(__MENU, fun, key).then(result => __MENU);
     }
     }
}
}
Zeile 1.894: Zeile 1.650:
// Zeigt den Eintrag im Menu einer Option
// Zeigt den Eintrag im Menu einer Option
// opt: Config und Value der Option
// opt: Config und Value der Option
// return Promise von GM.registerMenuCommand() (oder String-Version des Wertes)
function registerOption(opt) {
function registerOption(opt) {
     const __CONFIG = getOptConfig(opt);
     const __CONFIG = getOptConfig(opt);
Zeile 1.906: Zeile 1.661:
     if (! __CONFIG.HiddenMenu) {
     if (! __CONFIG.HiddenMenu) {
         switch (__CONFIG.Type) {
         switch (__CONFIG.Type) {
         case __OPTTYPES.MC : return registerNextMenuOption(__VALUE, __CONFIG.Choice, __LABEL, __ACTION, __HOTKEY);
         case __OPTTYPES.MC : registerNextMenuOption(__VALUE, __CONFIG.Choice, __LABEL, __ACTION, __HOTKEY);
         case __OPTTYPES.SW : return registerMenuOption(__VALUE, __LABEL, __ACTION, __HOTKEY,
                            break;
                                                      __CONFIG.AltLabel, __ACTION, __CONFIG.AltHotkey);
         case __OPTTYPES.SW : registerMenuOption(__VALUE, __LABEL, __ACTION, __HOTKEY,
         case __OPTTYPES.TF : return registerMenuOption(__VALUE, __LABEL, __ACTION, __HOTKEY,
                                                __CONFIG.AltLabel, __ACTION, __CONFIG.AltHotkey);
                                                      __CONFIG.AltLabel, opt.AltAction, __CONFIG.AltHotkey);
                            break;
         case __OPTTYPES.SD : return registerDataOption(__VALUE, __LABEL, __ACTION, __HOTKEY, __HIDDEN, __SERIAL);
         case __OPTTYPES.TF : registerMenuOption(__VALUE, __LABEL, __ACTION, __HOTKEY,
         case __OPTTYPES.SI : return registerDataOption(__VALUE, __LABEL, __ACTION, __HOTKEY, __HIDDEN, __SERIAL);
                                                __CONFIG.AltLabel, opt.AltAction, __CONFIG.AltHotkey);
         default :            return Promise.resolve(__VALUE);
                            break;
         case __OPTTYPES.SD : registerDataOption(__VALUE, __LABEL, __ACTION, __HOTKEY, __HIDDEN, __SERIAL);
                            break;
         case __OPTTYPES.SI : registerDataOption(__VALUE, __LABEL, __ACTION, __HOTKEY, __HIDDEN, __SERIAL);
                            break;
         default :            break;
         }
         }
     } else {
     } else {
         // Nur Anzeige im Log...
         // Nur Anzeige im Log...
         return registerDataOption(__VALUE, __LABEL, __ACTION, __HOTKEY, __HIDDEN, __SERIAL);
         registerDataOption(__VALUE, __LABEL, __ACTION, __HOTKEY, __HIDDEN, __SERIAL);
     }
     }
}
}
Zeile 1.969: Zeile 1.729:
         switch (optAction) {
         switch (optAction) {
         case __OPTACTION.SET : fun = function() {
         case __OPTACTION.SET : fun = function() {
                                       return setOptByName(optSet, item, __CONFIG.SetValue, __RELOAD).catch(defaultCatch);
                                       return setOptByName(optSet, item, __CONFIG.SetValue, __RELOAD);
                                   };
                                   };
                               break;
                               break;
         case __OPTACTION.NXT : fun = function() {
         case __OPTACTION.NXT : fun = function() {
                                       return promptNextOptByName(optSet, item, __CONFIG.SetValue, __RELOAD,
                                       return promptNextOptByName(optSet, item, __CONFIG.SetValue, __RELOAD,
                                                   __CONFIG.FreeValue, __CONFIG.SelValue, __CONFIG.MinChoice).catch(defaultCatch);
                                                   __CONFIG.FreeValue, __CONFIG.SelValue, __CONFIG.MinChoice);
                                   };
                                   };
                               break;
                               break;
         case __OPTACTION.RST : fun = function() {
         case __OPTACTION.RST : fun = function() {
                                       return resetOptions(optSet, __RELOAD).then(
                                       return resetOptions(optSet, __RELOAD);
                                              result => __LOG[3]("RESETTING (" + result + ")..."),
                                              defaultCatch);
                                   };
                                   };
                               break;
                               break;
Zeile 2.029: Zeile 1.787:
         const __OBJREF = getSharedRef(__SHARED, item);  // Gemeinsame Daten
         const __OBJREF = getSharedRef(__SHARED, item);  // Gemeinsame Daten


         if (getValue(__SHARED.item, '$') !== '$') {  // __OBJREF ist ein Item
         if (getValue(__SHARED.item, '$') !== '$') {  // __REF ist ein Item
             const __REF = valueOf(__OBJREF);
             const __REF = valueOf(__OBJREF);


Zeile 2.035: Zeile 1.793:
             addProps(config, getOptConfig(__REF));
             addProps(config, getOptConfig(__REF));
             addProps(config, optConfig);
             addProps(config, optConfig);
             config.setConst('SharedData', getOptValue(__REF), false);   // Wert muss schon da sein, NICHT nachladen, sonst ggfs. Promise
             config.setConst('SharedData', getOptValue(__REF));
         } else {  // __OBJREF enthaelt die Daten selbst
         } else {  // __REF enthaelt die Daten selbst
             if (! config.Name) {
             if (! config.Name) {
                 config.Name = __OBJREF.getPath();
                 config.Name = __OBJREF.getPath();
Zeile 2.067: Zeile 1.825:
             const __CONFIG = getSharedConfig(__OPTCONFIG, opt);
             const __CONFIG = getSharedConfig(__OPTCONFIG, opt);
             const __ALTACTION = getValue(__CONFIG.AltAction, __CONFIG.Action);
             const __ALTACTION = getValue(__CONFIG.AltAction, __CONFIG.Action);
             // Gab es vorher einen Aufruf, der einen Stub-Eintrag erzeugt hat, und wurden Daten geladen?
             // Gab es vorher einen Aufruf, der einen Stub-Eintrag erzeugt hat? Wurde ggfs. bereits geaendert...
             const __LOADED = ((preInit === false) && optSet[opt].Loaded);
             const __USESTUB = ((preInit === false) && __PREINIT);
             const __PROMISE = ((__LOADED || ! optSet[opt]) ? undefined : optSet[opt].Promise);
             const __LOADED = (__USESTUB && optSet[opt].Loaded);
             const __VALUE = (__LOADED ? optSet[opt].Value : undefined);
             const __VALUE = (__USESTUB ? optSet[opt].Value : undefined);


             optSet[opt] = {
             optSet[opt] = {
Zeile 2.076: Zeile 1.834:
                 'Config'    : __CONFIG,
                 'Config'    : __CONFIG,
                 'Loaded'    : (__ISSHARED || __LOADED),
                 'Loaded'    : (__ISSHARED || __LOADED),
                'Promise'  : __PROMISE,
                 'Value'    : initOptValue(__CONFIG, __VALUE),
                 'Value'    : initOptValue(__CONFIG, __VALUE),
                 'SetValue'  : __CONFIG.SetValue,
                 'SetValue'  : __CONFIG.SetValue,
Zeile 2.088: Zeile 1.845:
                 'Config'    : __OPTCONFIG,
                 'Config'    : __OPTCONFIG,
                 'Loaded'    : false,
                 'Loaded'    : false,
                'Promise'  : undefined,
                 'Value'    : initOptValue(__OPTCONFIG),
                 'Value'    : initOptValue(__OPTCONFIG),
                 'ReadOnly'  : (__ISSHARED || __OPTCONFIG.ReadOnly)
                 'ReadOnly'  : (__ISSHARED || __OPTCONFIG.ReadOnly)
Zeile 2.121: Zeile 1.877:
// optConfig: Konfiguration der Optionen
// optConfig: Konfiguration der Optionen
// optSet: Platz fuer die gesetzten Optionen
// optSet: Platz fuer die gesetzten Optionen
// return Promise auf gefuelltes Objekt mit den gesetzten Optionen
// return Gefuelltes Objekt mit den gesetzten Optionen
async function startOptions(optConfig, optSet = undefined, classification = undefined) {
function startOptions(optConfig, optSet = undefined, classification = undefined) {
     optSet = initOptions(optConfig, optSet, true);  // PreInit
     optSet = initOptions(optConfig, optSet, true);  // PreInit


     // Memory Storage fuer vorherige Speicherung...
     // Memory Storage fuer vorherige Speicherung...
     myOptMemSize = getMemSize(myOptMem = await restoreMemoryByOpt(optSet.oldStorage));
     myOptMemSize = getMemSize(myOptMem = restoreMemoryByOpt(optSet.oldStorage));


     // Zwischengespeicherte Befehle auslesen...
     // Zwischengespeicherte Befehle auslesen...
     const __STOREDCMDS = getStoredCmds(myOptMem);
     const __STOREDCMDS = getStoredCmds(myOptMem);


     // ... ermittelte Befehle ausfuehren...
     // ... ermittelte Befehle ausführen...
     const __LOADEDCMDS = await runStoredCmds(__STOREDCMDS, optSet, true);  // BeforeLoad
     const __LOADEDCMDS = runStoredCmds(__STOREDCMDS, optSet, true);  // BeforeLoad


     // Bisher noch nicht geladenene Optionen laden...
     // Bisher noch nicht geladenene Optionen laden...
     await loadOptions(optSet);
     loadOptions(optSet);


     // Memory Storage fuer naechste Speicherung...
     // Memory Storage fuer naechste Speicherung...
Zeile 2.147: Zeile 1.903:
     if (classification !== undefined) {
     if (classification !== undefined) {
         // Umbenennungen durchfuehren...
         // Umbenennungen durchfuehren...
         await classification.renameOptions();
         classification.renameOptions();
     }
     }


     // ... ermittelte Befehle ausfuehren...
     // ... ermittelte Befehle ausführen...
     await runStoredCmds(__LOADEDCMDS, optSet, false);  // Rest
     runStoredCmds(__LOADEDCMDS, optSet, false);  // Rest


     // Als globale Daten speichern...
     // Als globale Daten speichern...
Zeile 2.168: Zeile 1.924:
// 'formWidth': Anzahl der Elemente pro Zeile
// 'formWidth': Anzahl der Elemente pro Zeile
// 'formBreak': Elementnummer des ersten Zeilenumbruchs
// 'formBreak': Elementnummer des ersten Zeilenumbruchs
// return Liefert die gesetzten Optionen zurueck
function showOptions(optSet = undefined, optParams = { 'hideMenu' : false }) {
function showOptions(optSet = undefined, optParams = { 'hideMenu' : false }) {
     if (! optParams.hideMenu) {
     if (! optParams.hideMenu) {
         buildMenu(optSet).then(() => __LOG[3]("Menu OK"));
         buildMenu(optSet);
     }
     }


Zeile 2.177: Zeile 1.932:
         buildForm(optParams.menuAnchor, optSet, optParams);
         buildForm(optParams.menuAnchor, optSet, optParams);
     }
     }
    return optSet;
}
}


Zeile 2.186: Zeile 1.939:
// value: (Bei allen Typen) Zu setzender Wert
// value: (Bei allen Typen) Zu setzender Wert
// reload: Seite mit neuem Wert neu laden
// reload: Seite mit neuem Wert neu laden
// onFulfilled: Reaktion auf Speicherung im resolve-Fall (1. Promise.then()-Parameter)
// onRejected: Reaktion auf Speicherung im reject-Fall (2. Promise.then()-Parameter)
// return Gesetzter Wert
// return Gesetzter Wert
function setOpt(opt, value, reload = false, onFulfilled = undefined, onRejected = undefined) {
function setOpt(opt, value, reload = false) {
     return setOptValue(opt, setStored(getOptName(opt), value, reload, getOptConfig(opt).Serial, onFulfilled, onRejected));
     return setOptValue(opt, setStored(getOptName(opt), value, reload, getOptConfig(opt).Serial));
}
}


Zeile 2.217: Zeile 1.968:
// value: Default fuer ggfs. zu setzenden Wert
// value: Default fuer ggfs. zu setzenden Wert
// reload: Seite mit neuem Wert neu laden
// reload: Seite mit neuem Wert neu laden
// onFulfilled: Reaktion auf Speicherung im resolve-Fall (1. Promise.then()-Parameter)
// onRejected: Reaktion auf Speicherung im reject-Fall (2. Promise.then()-Parameter)
// return Gesetzter Wert
// return Gesetzter Wert
function setNextOpt(opt, value = undefined, reload = false, onFulfilled = undefined, onRejected = undefined) {
function setNextOpt(opt, value = undefined, reload = false) {
     return setOpt(opt, getNextOpt(opt, value), reload, onFulfilled, onRejected);
     return setOpt(opt, getNextOpt(opt, value), reload);
}
}


Zeile 2.230: Zeile 1.979:
// freeValue: Angabe, ob Freitext zugelassen ist (Default: false)
// freeValue: Angabe, ob Freitext zugelassen ist (Default: false)
// minChoice: Ab wievielen Auswahlmoeglichkeiten soll abgefragt werden? (Default: 3)
// minChoice: Ab wievielen Auswahlmoeglichkeiten soll abgefragt werden? (Default: 3)
// onFulfilled: Reaktion auf Speicherung im resolve-Fall (1. Promise.then()-Parameter)
// onRejected: Reaktion auf Speicherung im reject-Fall (2. Promise.then()-Parameter)
// return Gesetzter Wert
// return Gesetzter Wert
function promptNextOpt(opt, value = undefined, reload = false, freeValue = false, selValue = true, minChoice = 3, onFulfilled = undefined, onRejected = undefined) {
function promptNextOpt(opt, value = undefined, reload = false, freeValue = false, selValue = true, minChoice = 3) {
     const __CONFIG = getOptConfig(opt);
     const __CONFIG = getOptConfig(opt);
     const __CHOICE = __CONFIG.Choice;
     const __CHOICE = __CONFIG.Choice;


     if (value || (! __CHOICE) || (__CHOICE.length < minChoice)) {
     if (value || (! __CHOICE) || (__CHOICE.length < minChoice)) {
         return setNextOpt(opt, value, reload, onFulfilled, onRejected);
         return setNextOpt(opt, value, reload);
     }
     }


Zeile 2.251: Zeile 1.998:
                 message += (index + 1) + ") " + __CHOICE[index] + '\n';
                 message += (index + 1) + ") " + __CHOICE[index] + '\n';
             }
             }
             message += "\nNummer oder Wert eingeben:";
             message += "\nNummer eingeben:";
         } else {
         } else {
             message = __CHOICE.join(" / ") + "\n\nWert eingeben:";
             message = __CHOICE.join(" / ") + "\n\nWert eingeben:";
Zeile 2.273: Zeile 2.020:
             if (nextVal !== __VALUE) {
             if (nextVal !== __VALUE) {
                 if (nextVal) {
                 if (nextVal) {
                     return setOpt(opt, nextVal, reload, onFulfilled, onRejected);
                     return setOpt(opt, nextVal, reload);
                 }
                 }


                 const __LABEL = substParam(__CONFIG.Label, __VALUE);
                 const __LABEL = __CONFIG.Label.replace('$', __VALUE);


                 showAlert(__LABEL, "Ung\xFCltige Eingabe: " + __ANSWER);
                 showAlert(__LABEL, "Ung\xFCltige Eingabe: " + __ANSWER);
Zeile 2.282: Zeile 2.029:
         }
         }
     } catch (ex) {
     } catch (ex) {
         __LOG[0]("promptNextOpt: " + ex.message);
         __LOG[1]("promptNextOpt: " + ex.message);
     }
     }


Zeile 2.294: Zeile 2.041:
// value: (Bei allen Typen) Zu setzender Wert
// value: (Bei allen Typen) Zu setzender Wert
// reload: Seite mit neuem Wert neu laden
// reload: Seite mit neuem Wert neu laden
// onFulfilled: Reaktion auf Speicherung im resolve-Fall (1. Promise.then()-Parameter)
// onRejected: Reaktion auf Speicherung im reject-Fall (2. Promise.then()-Parameter)
// return Gesetzter Wert
// return Gesetzter Wert
function setOptByName(optSet, item, value, reload = false, onFulfilled = undefined, onRejected = undefined) {
function setOptByName(optSet, item, value, reload = false) {
     const __OPT = getOptByName(optSet, item);
     const __OPT = getOptByName(optSet, item);


     return setOpt(__OPT, value, reload, onFulfilled, onRejected);
     return setOpt(__OPT, value, reload);
}
}


Zeile 2.319: Zeile 2.064:
// value: Default fuer ggfs. zu setzenden Wert
// value: Default fuer ggfs. zu setzenden Wert
// reload: Seite mit neuem Wert neu laden
// reload: Seite mit neuem Wert neu laden
// onFulfilled: Reaktion auf Speicherung im resolve-Fall (1. Promise.then()-Parameter)
// onRejected: Reaktion auf Speicherung im reject-Fall (2. Promise.then()-Parameter)
// return Gesetzter Wert
// return Gesetzter Wert
function setNextOptByName(optSet, item, value = undefined, reload = false, onFulfilled = undefined, onRejected = undefined) {
function setNextOptByName(optSet, item, value = undefined, reload = false) {
     const __OPT = getOptByName(optSet, item);
     const __OPT = getOptByName(optSet, item);


     return setNextOpt(__OPT, value, reload, onFulfilled, onRejected);
     return setNextOpt(__OPT, value, reload);
}
}


Zeile 2.335: Zeile 2.078:
// freeValue: Angabe, ob Freitext zugelassen ist (Default: false)
// freeValue: Angabe, ob Freitext zugelassen ist (Default: false)
// minChoice: Ab wievielen Auswahlmoeglichkeiten soll abgefragt werden? (Default: 3)
// minChoice: Ab wievielen Auswahlmoeglichkeiten soll abgefragt werden? (Default: 3)
// onFulfilled: Reaktion auf Speicherung im resolve-Fall (1. Promise.then()-Parameter)
// onRejected: Reaktion auf Speicherung im reject-Fall (2. Promise.then()-Parameter)
// return Gesetzter Wert
// return Gesetzter Wert
function promptNextOptByName(optSet, item, value = undefined, reload = false, freeValue = false, selValue = true, minChoice = 3, onFulfilled = undefined, onRejected = undefined) {
function promptNextOptByName(optSet, item, value = undefined, reload = false, freeValue = false, selValue = true, minChoice = 3) {
     const __OPT = getOptByName(optSet, item);
     const __OPT = getOptByName(optSet, item);


     return promptNextOpt(__OPT, value, reload, freeValue, selValue, minChoice, onFulfilled, onRejected);
     return promptNextOpt(__OPT, value, reload, freeValue, selValue, minChoice);
}
}


// Baut das Benutzermenu auf (asynchron im Hintergrund)
// Baut das Benutzermenu auf
// optSet: Gesetzte Optionen
// optSet: Gesetzte Optionen
// return Promise auf void
function buildMenu(optSet) {
async function buildMenu(optSet) {
     __LOG[3]("buildMenu()");
     __LOG[3]("buildMenu()");


     for (let opt in optSet) {
     for (let opt in optSet) {
         await registerOption(optSet[opt]).then(
         registerOption(optSet[opt]);
                result => __LOG[6](`REGISTEROPTION[${opt}] = ${result}`),
                defaultCatch);
     }
     }
}
}
Zeile 2.360: Zeile 2.098:
// opt: Zu invalidierende Option
// opt: Zu invalidierende Option
// force: Invalidiert auch Optionen mit 'AutoReset'-Attribut
// force: Invalidiert auch Optionen mit 'AutoReset'-Attribut
// return Promise auf resultierenden Wert
function invalidateOpt(opt, force = false) {
function invalidateOpt(opt, force = false) {
     return Promise.resolve(opt.Promise).then(value => {
     if (! opt.ReadOnly) {
            if (opt.Loaded && ! opt.ReadOnly) {
        const __CONFIG = getOptConfig(opt);
                const __CONFIG = getOptConfig(opt);


                // Wert "ungeladen"...
        // Wert "ungeladen"...
                opt.Loaded = (force || ! __CONFIG.AutoReset);
        opt.Loaded = (force || ! __CONFIG.AutoReset);


                if (opt.Loaded && __CONFIG.AutoReset) {
        if (opt.Loaded && __CONFIG.AutoReset) {
                    // Nur zuruecksetzen, gilt als geladen...
            // Nur zuruecksetzen, gilt als geladen...
                    setOptValue(opt, initOptValue(__CONFIG));
            setOptValue(opt, initOptValue(__CONFIG));
                }
        }
            }
    }
 
            return getOptValue(opt);
        }, defaultCatch);
}
}


// Invalidiert die (ueber Menu) gesetzten Optionen
// Invalidiert die (ueber Menu) gesetzten Optionen
// optSet: Object mit den Optionen
// optSet: Set mit den Optionen
// force: Invalidiert auch Optionen mit 'AutoReset'-Attribut
// force: Invalidiert auch Optionen mit 'AutoReset'-Attribut
// return Promise auf Object mit den geladenen Optionen
// return Set mit den geladenen Optionen
async function invalidateOpts(optSet, force = false) {
function invalidateOpts(optSet, force = false) {
     for (let opt in optSet) {
     for (let opt in optSet) {
         const __OPT = optSet[opt];
         const __OPT = optSet[opt];


         await invalidateOpt(__OPT, force);
         if (__OPT.Loaded) {
            invalidateOpt(__OPT, force);
        }
     }
     }


Zeile 2.396: Zeile 2.131:
// opt: Zu ladende Option
// opt: Zu ladende Option
// force: Laedt auch Optionen mit 'AutoReset'-Attribut
// force: Laedt auch Optionen mit 'AutoReset'-Attribut
// return Promise auf gesetzten Wert der gelandenen Option
// return Gesetzter Wert der gelandenen Option
function loadOption(opt, force = false) {
function loadOption(opt, force = false) {
     if (! opt.Promise) {
     const __CONFIG = getOptConfig(opt);
        const __CONFIG = getOptConfig(opt);
    const __ISSHARED = getValue(__CONFIG.Shared, false, true);
        const __ISSHARED = getValue(__CONFIG.Shared, false, true);
    const __NAME = getOptName(opt);
        const __NAME = getOptName(opt);
    const __DEFAULT = getOptValue(opt, undefined, false, false);
        const __DEFAULT = getOptValue(opt, undefined, false, false, false);
    let value;
        let value;


        if (opt.Loaded && ! __ISSHARED) {
    if (opt.Loaded && ! __ISSHARED) {
            const __ERROR = "Error: Oprion '" + __NAME + "' bereits geladen!";
        __LOG[1]("Error: Oprion '" + __NAME + "' bereits geladen!");
    }


            __LOG[0](__MESSAGE);
    if (opt.ReadOnly || __ISSHARED) {
 
        value = __DEFAULT;
            return Promise.reject(__MESSAGE);
    } else if (! force && __CONFIG.AutoReset) {
        }
        value = initOptValue(__CONFIG);
    } else {
        value = (__CONFIG.Serial ?
                        deserialize(__NAME, __DEFAULT) :
                        GM_getValue(__NAME, __DEFAULT));
    }


        if (opt.ReadOnly || __ISSHARED) {
    __LOG[5]("LOAD " + __NAME + ": " + __LOG.changed(__DEFAULT, value));
            value = __DEFAULT;
        } else if (! force && __CONFIG.AutoReset) {
            value = initOptValue(__CONFIG);
        } else {
            value = (__CONFIG.Serial ?
                            deserialize(__NAME, __DEFAULT) :
                            GM.getValue(__NAME, __DEFAULT));
        }


        opt.Promise = Promise.resolve(value).then(value => {
    // Wert als geladen markieren...
                // Paranoide Sicherheitsabfrage (das sollte nie passieren!)...
    opt.Loaded = true;
                if (opt.Loaded || ! opt.Promise) {
                    showAlert("Error", "Unerwarteter Widerspruch zwischen opt.Loaded und opt.Promise", safeStringify(opt));
                }
                __LOG[5]("LOAD " + __NAME + ": " + __LOG.changed(__DEFAULT, value));


                // Wert intern setzen...
    // Wert intern setzen...
                const __VAL = setOptValue(opt, value);
    return setOptValue(opt, value);
 
                // Wert als geladen markieren...
                opt.Promise = undefined;
                opt.Loaded = true;
 
                return __VAL;
            }, defaultCatch);
    }
 
    return opt.Promise;
}
}


// Laedt die (ueber Menu) gesetzten Optionen
// Laedt die (ueber Menu) gesetzten Optionen
// optSet: Object mit den Optionen
// optSet: Set mit den Optionen
// force: Laedt auch Optionen mit 'AutoReset'-Attribut
// force: Laedt auch Optionen mit 'AutoReset'-Attribut
// return Array mit Promises neuer Ladevorgaenge (fuer Objekte mit 'name' und 'value')
// return Set mit den geladenen Optionen
function loadOptions(optSet, force = false) {
function loadOptions(optSet, force = false) {
    const __PROMISES = [];
     for (let opt in optSet) {
     for (let opt in optSet) {
         const __OPT = optSet[opt];
         const __OPT = optSet[opt];


         if (! __OPT.Loaded) {
         if (! __OPT.Loaded) {
             const __PROMISE = loadOption(__OPT, force).then(value => {
             loadOption(__OPT, force);
                    __LOG[5]("LOADED " + opt + " << " + value);
 
                    return Promise.resolve({
                            'name'  : opt,
                            'value' : value
                        });
                }, defaultCatch);
 
            __PROMISES.push(__PROMISE);
         }
         }
     }
     }


     return Promise.all(__PROMISES);
     return optSet;
}
}


Zeile 2.474: Zeile 2.181:
// opt: Gesetzte Option
// opt: Gesetzte Option
// force: Entfernt auch Optionen mit 'Permanent'-Attribut
// force: Entfernt auch Optionen mit 'Permanent'-Attribut
// reset: Setzt bei Erfolg auf Initialwert der Option (auch fuer nicht 'AutoReset')
// reset: Setzt bei Erfolg auf Initialwert der Option
// return Promise von GM.deleteValue() (oder void)
function deleteOption(opt, force = false, reset = true) {
function deleteOption(opt, force = false, reset = true) {
     const __CONFIG = getOptConfig(opt);
     const __CONFIG = getOptConfig(opt);
Zeile 2.484: Zeile 2.190:
         __LOG[4]("DELETE " + __NAME);
         __LOG[4]("DELETE " + __NAME);


         return GM.deleteValue(__NAME).then(voidValue => {
         GM_deleteValue(__NAME);
                if (reset || __CONFIG.AutoReset) {
 
                    setOptValue(opt, initOptValue(__CONFIG));
        if (reset) {
                }
            setOptValue(opt, initOptValue(__CONFIG));
            }, defaultCatch);
        }
     }
     }
    return Promise.resolve();
}
}


Zeile 2.499: Zeile 2.203:
// force: Entfernt auch Optionen mit 'Permanent'-Attribut
// force: Entfernt auch Optionen mit 'Permanent'-Attribut
// reset: Setzt bei Erfolg auf Initialwert der Option
// reset: Setzt bei Erfolg auf Initialwert der Option
// return Promise auf diesen Vorgang
function deleteOptions(optSet, optSelect = undefined, force = false, reset = true) {
async function deleteOptions(optSet, optSelect = undefined, force = false, reset = true) {
     const __DELETEALL = (optSelect === undefined) || (optSelect === true);
     const __DELETEALL = ((optSelect === undefined) || (optSelect === true));
     const __OPTSELECT = getValue(optSelect, { });
     const __OPTSELECT = getValue(optSelect, { });


     for (let opt in optSet) {
     for (let opt in optSet) {
         if (getValue(__OPTSELECT[opt], __DELETEALL)) {
         if (getValue(__OPTSELECT[opt], __DELETEALL)) {
             await deleteOption(optSet[opt], force, reset);
             deleteOption(optSet[opt], force, reset);
         }
         }
     }
     }
    return Promise.resolve();
}
}


Zeile 2.518: Zeile 2.219:
// reload: Wert nachladen statt beizubehalten
// reload: Wert nachladen statt beizubehalten
// force: Laedt auch Optionen mit 'AutoReset'-Attribut
// force: Laedt auch Optionen mit 'AutoReset'-Attribut
// return Promise auf umbenannte Option
// return Umbenannte Option
async function renameOption(opt, name, reload = false, force = false) {
function renameOption(opt, name, reload = false, force = false) {
     const __NAME = getOptName(opt);
     const __NAME = getOptName(opt);


     if (__NAME !== name) {
     if (__NAME !== name) {
         await deleteOption(opt, true, ! reload);
         deleteOption(opt, true, ! reload);


         setOptName(opt, name);
         setOptName(opt, name);
        await invalidateOpt(opt, opt.Loaded);


         if (reload) {
         if (reload) {
             opt.Loaded = false;
             loadOption(opt, force);
 
            await loadOption(opt, force);
         }
         }
     }
     }


     return Promise.resolve(opt);
     return opt;
}
}


Zeile 2.564: Zeile 2.261:
// - name: Neu zu setzender Name (Speicheradresse)
// - name: Neu zu setzender Name (Speicheradresse)
// - param: Parameter "renameParam" von oben, z.B. Prefix oder Postfix
// - param: Parameter "renameParam" von oben, z.B. Prefix oder Postfix
// return Promise auf diesen Vorgang
function renameOptions(optSet, optSelect, renameParam = undefined, renameFun = prefixName) {
async function renameOptions(optSet, optSelect, renameParam = undefined, renameFun = prefixName) {
     if (renameFun === undefined) {
     if (renameFun === undefined) {
         __LOG[0]("RENAME: Illegale Funktion!");
         __LOG[1]("RENAME: Illegale Funktion!");
     }
     }
     for (let opt in optSelect) {
     for (let opt in optSelect) {
Zeile 2.574: Zeile 2.270:


         if (__OPT === undefined) {
         if (__OPT === undefined) {
             __LOG[0]("RENAME: Option '" + opt + "' nicht gefunden!");
             __LOG[1]("RENAME: Option '" + opt + "' nicht gefunden!");
         } else {
         } else {
             const __NAME = getOptName(__OPT);
             const __NAME = getOptName(__OPT);
Zeile 2.584: Zeile 2.280:
             const __FORCE = (__ISSCALAR ? true : __OPTPARAMS.force);
             const __FORCE = (__ISSCALAR ? true : __OPTPARAMS.force);


             await renameOption(__OPT, __NEWNAME, __RELOAD, __FORCE);
             renameOption(__OPT, __NEWNAME, __RELOAD, __FORCE);
         }
         }
     }
     }
Zeile 2.592: Zeile 2.288:
// optSet: Gesetzte Optionen
// optSet: Gesetzte Optionen
// reload: Seite mit "Werkseinstellungen" neu laden
// reload: Seite mit "Werkseinstellungen" neu laden
// return Promise auf diesen Vorgang
function resetOptions(optSet, reload = true) {
async function resetOptions(optSet, reload = true) {
     // Alle (nicht 'Permanent') gesetzten Optionen entfernen...
     // Alle (nicht 'Permanent') gesetzten Optionen entfernen...
     await deleteOptions(optSet, true, false, ! reload);
     deleteOptions(optSet, true, false, ! reload);


     // ... und ggfs. Seite neu laden (mit "Werkseinstellungen")...
     if (reload) {
    refreshPage(reload);
        // ... und Seite neu laden (mit "Werkseinstellungen")...
        window.location.reload();
    }
}
}


Zeile 2.608: Zeile 2.305:
// type: Typ der Input-Felder (Default: unsichtbare Daten)
// type: Typ der Input-Felder (Default: unsichtbare Daten)
// return Ergaenztes Form-Konstrukt
// return Ergaenztes Form-Konstrukt
function addInputField(form, props, type = 'hidden') {
function addInputField(form, props, type = "hidden") {
     for (let fieldName in props) {
     for (let fieldName in props) {
         let field = form[fieldName];
         let field = form[fieldName];
         if (! field) {
         if (! field) {
             field = document.createElement('input');
             field = document.createElement("input");
             field.type = type;
             field.type = type;
             field.name = fieldName;
             field.name = fieldName;
Zeile 2.628: Zeile 2.325:
// return Ergaenztes Form-Konstrukt
// return Ergaenztes Form-Konstrukt
function addHiddenField(form, props) {
function addHiddenField(form, props) {
     return addInputField(form, props, 'hidden');
     return addInputField(form, props, "hidden");
}
}


Zeile 2.641: Zeile 2.338:
         return obj.addEventListener(type, callback, capture);
         return obj.addEventListener(type, callback, capture);
     } else if (obj.attachEvent) {
     } else if (obj.attachEvent) {
         return obj.attachEvent('on' + type, callback);
         return obj.attachEvent("on" + type, callback);
     } else {
     } else {
         __LOG[0]("Could not add " + type + " event:");
         __LOG[1]("Could not add " + type + " event:");
         __LOG[2](callback);
         __LOG[2](callback);


Zeile 2.660: Zeile 2.357:
         return obj.removeEventListener(type, callback, capture);
         return obj.removeEventListener(type, callback, capture);
     } else if (obj.detachEvent) {
     } else if (obj.detachEvent) {
         return obj.detachEvent('on' + type, callback);
         return obj.detachEvent("on" + type, callback);
     } else {
     } else {
         __LOG[0]("Could not remove " + type + " event:");
         __LOG[1]("Could not remove " + type + " event:");
         __LOG[2](callback);
         __LOG[2](callback);


Zeile 2.699: Zeile 2.396:
// return Gesuchtes Element mit der lfd. Nummer index oder undefined (falls nicht gefunden)
// return Gesuchtes Element mit der lfd. Nummer index oder undefined (falls nicht gefunden)
function getElement(name, index = 0, doc = document) {
function getElement(name, index = 0, doc = document) {
     const __TAGS = doc.getElementsByName(name);
     const __TAGS = document.getElementsByName(name);
     const __TABLE = (__TAGS ? __TAGS[index] : undefined);
     const __TABLE = (__TAGS === undefined) ? undefined : __TAGS[index];


     return __TABLE;
     return __TABLE;
Zeile 2.710: Zeile 2.407:
// doc: Dokument (document)
// doc: Dokument (document)
// return Gesuchtes Element oder undefined (falls nicht gefunden)
// return Gesuchtes Element oder undefined (falls nicht gefunden)
function getTable(index, tag = 'table', doc = document) {
function getTable(index, tag = "table", doc = document) {
     const __TAGS = doc.getElementsByTagName(tag);
     const __TAGS = document.getElementsByTagName(tag);
     const __TABLE = (__TAGS ? __TAGS[index] : undefined);
     const __TABLE = (__TAGS === undefined) ? undefined : __TAGS[index];


     return __TABLE;
     return __TABLE;
}
// Hilfsfunktion fuer die Ermittlung der Zeilen einer Tabelle
// name: Name des Tabellen-Elements (siehe "name=")
// index: Laufende Nummer des Tabellen-Elements (0-based), Default: 0
// doc: Dokument (document)
// return Gesuchte Zeilen oder undefined (falls nicht gefunden)
function getElementRows(name, index = 0, doc = document) {
    const __TABLE = getElement(name, index, doc);
    const __ROWS = (__TABLE ? __TABLE.rows : undefined);
    return __ROWS;
}
}


Zeile 2.734: Zeile 2.419:
// return Gesuchte Zeilen oder undefined (falls nicht gefunden)
// return Gesuchte Zeilen oder undefined (falls nicht gefunden)
function getRows(index, doc = document) {
function getRows(index, doc = document) {
     const __TABLE = getTable(index, 'table', doc);
     const __TABLE = getTable(index, "table", doc);
     const __ROWS = (__TABLE ? __TABLE.rows : undefined);
     const __ROWS = (__TABLE === undefined) ? undefined : __TABLE.rows;
 
    return __ROWS;
}
 
// Hilfsfunktion fuer die Ermittlung der Zeilen einer Tabelle
// id: ID des Tabellen-Elements
// doc: Dokument (document)
// return Gesuchte Zeilen oder undefined (falls nicht gefunden)
function getRowsById(id, doc = document) {
    const __TABLE = doc.getElementById(id);
    const __ROWS = (__TABLE ? __TABLE.rows : undefined);


     return __ROWS;
     return __ROWS;
Zeile 2.777: Zeile 2.451:
         const __CONFIG = getOptConfig(opt);
         const __CONFIG = getOptConfig(opt);
         const __SERIAL = getValue(serial, getValue(__CONFIG.Serial, false));
         const __SERIAL = getValue(serial, getValue(__CONFIG.Serial, false));
         const __THISVAL = ((__CONFIG.ValType === 'String') ? "'\\x22' + this.value + '\\x22'" : "this.value");
         const __THISVAL = ((__CONFIG.ValType === "String") ? "'\\x22' + this.value + '\\x22'" : "this.value");
         const __TVALUE = getValue(__CONFIG.ValType, __THISVAL, "new " + __CONFIG.ValType + '(' + __THISVAL + ')');
         const __TVALUE = getValue(__CONFIG.ValType, __THISVAL, "new " + __CONFIG.ValType + '(' + __THISVAL + ')');
         const __VALSTR = ((value !== undefined) ? safeStringify(value) : __SERIAL ? "JSON.stringify(" + __TVALUE + ')' : __TVALUE);
         const __VALSTR = ((value !== undefined) ? safeStringify(value) : __SERIAL ? "JSON.stringify(" + __TVALUE + ')' : __TVALUE);
Zeile 2.806: Zeile 2.480:
// memory: __OPTMEM.normal = unbegrenzt gespeichert (localStorage), __OPTMEM.begrenzt = bis Browserende gespeichert (sessionStorage), __OPTMEM.inaktiv
// memory: __OPTMEM.normal = unbegrenzt gespeichert (localStorage), __OPTMEM.begrenzt = bis Browserende gespeichert (sessionStorage), __OPTMEM.inaktiv
// return String mit dem (reinen) Funktionsaufruf
// return String mit dem (reinen) Funktionsaufruf
function getFormActionEvent(opt, isAlt = false, value = undefined, type = 'click', serial = undefined, memory = undefined) {
function getFormActionEvent(opt, isAlt = false, value = undefined, type = "click", serial = undefined, memory = undefined) {
     const __ACTION = getFormAction(opt, isAlt, value, serial, memory);
     const __ACTION = getFormAction(opt, isAlt, value, serial, memory);


Zeile 2.812: Zeile 2.486:
}
}


// Hilfsfunktion: Wendet eine Konvertierung auf jede "Zeile" innerhalb eines Textes an
// Zeigt eine Option auf der Seite als Auswahlbox an
// text: Urspruenglicher Text
// opt: Anzuzeigende Option
// convFun: function(line, index, arr): Konvertiert line in "Zeile" line des Arrays arr
// return String mit dem HTML-Code
// separator: Zeilentrenner im Text (Default: '\n')
function getOptionSelect(opt) {
// thisArg: optionaler this-Parameter fuer die Konvertierung
     const __CONFIG = getOptConfig(opt);
// limit: optionale Begrenzung der Zeilen
     const __NAME = getOptName(opt);
// return String mit dem neuen Text
     const __VALUE = getOptValue(opt);
function eachLine(text, convFun, separator = '\n', thisArg = undefined, limit = undefined) {
     const __ACTION = getFormActionEvent(opt, false, undefined, "change", undefined);
    const __ARR = text.split(separator, limit);
     const __FORMLABEL = getValue(__CONFIG.FormLabel, __CONFIG.Label);
    const __RES = __ARR.map(convFun, thisArg);
     const __LABEL = '<label for="' + __NAME + '">' + __FORMLABEL + '</label>';
 
     let element = '<select name="' + __NAME + '" id="' + __NAME + '"' + __ACTION + '>';
    return __RES.join(separator);
}
 
// Hilfsfunktion: Ergaenzt einen HTML-Code um einen Titel (ToolTip)
// html: Urspruenglicher HTML-Code (z.B. ein HTML-Element oder Text)
// title: Im ToolTip angezeigter Text
// separator: Zeilentrenner im Text (Default: '|')
// limit: optionale Begrenzung der Zeilen
// return String mit dem neuen HTML-Code
function withTitle(html, title, separator = '|', limit = undefined) {
    if (title && title.length) {
        return eachLine(html, line => '<abbr title="' + title + '">' + line + '</abbr>', separator, undefined, limit);
    } else {
        return html;
    }
}
 
// Hilfsfunktion: Ermittelt einen Label- oder FormLabel-Eintrag (Default)
// label: Config-Eintrag fuer Label oder FormLabel
// defLabel: Ersatzwert, falls label nicht angegeben
// isSelect: Angabe, ob ein Parameter angezeigt wird (Default: false)
// isForm: Angabe, ob ein FormLabel gesucht ist (Default: true)
// return Vollstaendiger Label- oder FormLabel-Eintrag
function formatLabel(label, defLabel = undefined, isSelect = false, isForm = true) {
    const __LABEL = getValue(label, defLabel);
 
    if (isSelect && __LABEL && (substParam(__LABEL, '_') === __LABEL)) {
        return __LABEL + (isForm ? "|$" : " $");
    } else {
        return __LABEL;
    }
}
 
// Zeigt eine Option auf der Seite als Auswahlbox an
// opt: Anzuzeigende Option
// return String mit dem HTML-Code
function getOptionSelect(opt) {
     const __CONFIG = getOptConfig(opt);
     const __NAME = getOptName(opt);
     const __VALUE = getOptValue(opt);
     const __ACTION = getFormActionEvent(opt, false, undefined, 'change', undefined);
     const __FORMLABEL = formatLabel(__CONFIG.FormLabel, __CONFIG.Label, true);
    const __TITLE = substParam(getValue(__CONFIG.Title, __CONFIG.Label), __VALUE);
     const __LABEL = '<label for="' + __NAME + '">' + __FORMLABEL + '</label>';
     let element = '<select name="' + __NAME + '" id="' + __NAME + '"' + __ACTION + '>';


     if (__CONFIG.FreeValue && ! (~ __CONFIG.Choice.indexOf(__VALUE))) {
     if (__CONFIG.FreeValue && ! (~ __CONFIG.Choice.indexOf(__VALUE))) {
Zeile 2.879: Zeile 2.508:
     element += '\n</select>';
     element += '\n</select>';


     return withTitle(substParam(__LABEL, element), __TITLE);
     return __LABEL.replace('$', element);
}
}


Zeile 2.889: Zeile 2.518:
     const __NAME = getOptName(opt);
     const __NAME = getOptName(opt);
     const __VALUE = getOptValue(opt, false);
     const __VALUE = getOptValue(opt, false);
     const __ACTION = getFormActionEvent(opt, false, true, 'click', false);
     const __ACTION = getFormActionEvent(opt, false, true, "click", false);
     const __ALTACTION = getFormActionEvent(opt, true, false, 'click', false);
     const __ALTACTION = getFormActionEvent(opt, true, false, "click", false);
    const __FORMLABEL = formatLabel(__CONFIG.FormLabel); // nur nutzen, falls angegeben
    const __TITLE = getValue(__CONFIG.Title, '$');
    const __TITLEON = substParam(__TITLE, __CONFIG.Label);
    const __TITLEOFF = substParam(getValue(__CONFIG.AltTitle, __TITLE), __CONFIG.AltLabel);
     const __ELEMENTON  = '<input type="radio" name="' + __NAME +
     const __ELEMENTON  = '<input type="radio" name="' + __NAME +
                         '" id="' + __NAME + 'ON" value="1"' +
                         '" id="' + __NAME + 'ON" value="1"' +
Zeile 2.905: Zeile 2.530:
                         ' /><label for="' + __NAME + 'OFF">' +
                         ' /><label for="' + __NAME + 'OFF">' +
                         __CONFIG.AltLabel + '</label>';
                         __CONFIG.AltLabel + '</label>';
    const __ELEMENT = [
                          withTitle(__FORMLABEL, __VALUE ? __TITLEON : __TITLEOFF),
                          withTitle(__ELEMENTON, __TITLEON),
                          withTitle(__ELEMENTOFF, __TITLEOFF)
                      ];


     return ((__FORMLABEL && __FORMLABEL.length) ? __ELEMENT : __ELEMENT.slice(1, 3));
     return [ __ELEMENTON, __ELEMENTOFF ];
}
}


Zeile 2.921: Zeile 2.541:
     const __NAME = getOptName(opt);
     const __NAME = getOptName(opt);
     const __VALUE = getOptValue(opt, false);
     const __VALUE = getOptValue(opt, false);
     const __ACTION = getFormActionEvent(opt, __VALUE, ! __VALUE, 'click', false);
     const __ACTION = getFormActionEvent(opt, __VALUE, ! __VALUE, "click", false);
     const __VALUELABEL = (__VALUE ? __CONFIG.Label : getValue(__CONFIG.AltLabel, __CONFIG.Label));
     const __FORMLABEL = getValue(__CONFIG.FormLabel, __CONFIG.Label);
    const __FORMLABEL = formatLabel(__CONFIG.FormLabel, __CONFIG.Label);
    const __TITLE = substParam(getValue(__VALUE ? __CONFIG.Title : getValue(__CONFIG.AltTitle, __CONFIG.Title), '$'), __VALUELABEL);


     return withTitle('<input type="checkbox" name="' + __NAME +
     return '<input type="checkbox" name="' + __NAME +
                    '" id="' + __NAME + '" value="' + __VALUE + '"' +
          '" id="' + __NAME + '" value="' + __VALUE + '"' +
                    (__VALUE ? ' CHECKED' : "") + __ACTION + ' /><label for="' +
          (__VALUE ? ' CHECKED' : "") + __ACTION + ' /><label for="' +
                    __NAME + '">' + __FORMLABEL + '</label>', __TITLE);
          __NAME + '">' + __FORMLABEL + '</label>';
}
}


Zeile 2.939: Zeile 2.557:
     const __NAME = getOptName(opt);
     const __NAME = getOptName(opt);
     const __VALUE = getOptValue(opt);
     const __VALUE = getOptValue(opt);
     const __ACTION = getFormActionEvent(opt, false, undefined, 'submit', undefined);
     const __ACTION = getFormActionEvent(opt, false, undefined, "submit", undefined);
     const __SUBMIT = getValue(__CONFIG.Submit, "");
     const __SUBMIT = getValue(__CONFIG.Submit, "");
     //const __ONSUBMIT = (__SUBMIT.length ? ' onKeyDown="' + __SUBMIT + '"': "");
     //const __ONSUBMIT = (__SUBMIT.length ? ' onKeyDown="' + __SUBMIT + '"': "");
     const __ONSUBMIT = (__SUBMIT ? ' onKeyDown="' + __SUBMIT + '"': "");
     const __ONSUBMIT = (__SUBMIT ? ' onKeyDown="' + __SUBMIT + '"': "");
     const __FORMLABEL = formatLabel(__CONFIG.FormLabel, __CONFIG.Label);
     const __FORMLABEL = getValue(__CONFIG.FormLabel, __CONFIG.Label);
    const __TITLE = substParam(getValue(__CONFIG.Title, '$'), __FORMLABEL);
     const __ELEMENTLABEL = '<label for="' + __NAME + '">' + __FORMLABEL + '</label>';
     const __ELEMENTLABEL = '<label for="' + __NAME + '">' + __FORMLABEL + '</label>';
     const __ELEMENTTEXT = '<textarea name="' + __NAME + '" id="' + __NAME + '" cols="' + __CONFIG.Cols +
     const __ELEMENTTEXT = '<textarea name="' + __NAME + '" id="' + __NAME + '" cols="' + __CONFIG.Cols +
Zeile 2.950: Zeile 2.567:
                           safeStringify(__VALUE, __CONFIG.Replace, __CONFIG.Space) + '</textarea>';
                           safeStringify(__VALUE, __CONFIG.Replace, __CONFIG.Space) + '</textarea>';


     return [ withTitle(__ELEMENTLABEL, __TITLE), __ELEMENTTEXT ];
     return [ __ELEMENTLABEL, __ELEMENTTEXT ];
}
}


Zeile 2.960: Zeile 2.577:
     const __NAME = getOptName(opt);
     const __NAME = getOptName(opt);
     const __VALUE = getOptValue(opt, false);
     const __VALUE = getOptValue(opt, false);
     const __ACTION = getFormActionEvent(opt, __VALUE, ! __VALUE, 'click', false);
     const __ACTION = getFormActionEvent(opt, __VALUE, ! __VALUE, "click", false);
     const __BUTTONLABEL = (__VALUE ? getValue(__CONFIG.AltLabel, __CONFIG.Label) : __CONFIG.Label);
     const __BUTTONLABEL = (__VALUE ? __CONFIG.AltLabel : __CONFIG.Label);
     const __FORMLABEL = formatLabel(__CONFIG.FormLabel, __BUTTONLABEL);
     const __FORMLABEL = getValue(__CONFIG.FormLabel, __CONFIG.Label);
    const __BUTTONTITLE = substParam(getValue(__VALUE ? getValue(__CONFIG.AltTitle, __CONFIG.Title) : __CONFIG.Title, '$'), __BUTTONLABEL);


     return '<label for="' + __NAME + '">' + __FORMLABEL + '</label>' +
     return '<label for="' + __NAME + '">' + __FORMLABEL +
          withTitle('<input type="button" name="" + ' + __NAME +
          '</label><input type="button" name="' + __NAME +
                    '" id="' + __NAME + '" value="' + __BUTTONLABEL +
          '" id="' + __NAME + '" value="' + __BUTTONLABEL + '"' +
                    '"' + __ACTION + '/>', __BUTTONTITLE);
          __ACTION + '/>';
}
}


Zeile 2.998: Zeile 2.614:
         }
         }


         if ((typeof element) !== 'string') {
         if (element.length === 2) {
             element = '<div>' + Array.from(element).join('<br />') + '</div>';
             element = '<div>' + element[0] + '<br />' + element[1] + '</div>';
         }
         }
     }
     }


     return element;
     return element;
}
// Gruppiert die Daten eines Objects nach einem Kriterium
// data: Object mit Daten
// byFun: function(val), die das Kriterium ermittelt. Default: value
// filterFun: function(key, index, arr), die das Kriterium key im Array arr an der Stelle index vergleicht. Default: Wert identisch
// sortFun: function(a, b), nach der die Kriterien sortiert werden. Default: Array.sort()
// return Neues Object mit Eintraegen der Form <Kriterium> : [ <alle Keys zu diesem Kriterium> ]
function groupData(data, byFun, filterFun, sortFun) {
    const __BYFUN = (byFun || (val => val));
    const __FILTERFUN = (filterFun || ((key, index, arr) => (arr[index] === key)));
    const __KEYS = Object.keys(data);
    const __VALS = Object.values(data);
    const __BYKEYS = __VALS.map(__BYFUN);
    const __BYKEYSET = new Set(__BYKEYS);
    const __BYKEYARRAY = [...__BYKEYSET];
    const __SORTEDKEYS = __BYKEYARRAY.sort(sortFun);
    const __GROUPEDKEYS = __SORTEDKEYS.map(byVal => __KEYS.filter((key, index, arr) => __FILTERFUN(byVal, index, __BYKEYS)));
    const __ASSIGN = ((keyArr, valArr) => Object.assign({ }, ...keyArr.map((key, index) => ({ [key] : valArr[index] }))));
    return __ASSIGN(__SORTEDKEYS, __GROUPEDKEYS);
}
}


Zeile 3.041: Zeile 2.636:
     const __FORMBREAK = getValue(optParams.formBreak, __FORMWIDTH);
     const __FORMBREAK = getValue(optParams.formBreak, __FORMWIDTH);
     const __SHOWFORM = getOptValue(optSet.showForm, true) ? optParams.showForm : { 'showForm' : true };
     const __SHOWFORM = getOptValue(optSet.showForm, true) ? optParams.showForm : { 'showForm' : true };
    const __PRIOOPTS = groupData(optSet, opt => getOptConfig(opt).FormPrio);
     let form = __FORM;
     let form = __FORM;
     let count = 0;  // Bisher angezeigte Optionen
     let count = 0;  // Bisher angezeigte Optionen
     let column = 0;  // Spalte der letzten Option (1-basierend)
     let column = 0;  // Spalte der letzten Option (1-basierend)


     for (let optKeys of Object.values(__PRIOOPTS)) {
     for (let opt in optSet) {
         for (let optKey of optKeys) {
         if (checkItem(opt, __SHOWFORM, optParams.hideForm)) {
            if (checkItem(optKey, __SHOWFORM, optParams.hideForm)) {
            const __ELEMENT = getOptionElement(optSet[opt]);
                const __ELEMENT = getOptionElement(optSet[optKey]);
            const __TDOPT = (~ __ELEMENT.indexOf('|')) ? "" : ' colspan="2"';
                const __TDOPT = ((~ __ELEMENT.indexOf('|')) ? "" : ' colspan="2"');


                if (__ELEMENT) {
            if (__ELEMENT) {
                    if (++count > __FORMBREAK) {
                if (++count > __FORMBREAK) {
                        if (++column > __FORMWIDTH) {
                    if (++column > __FORMWIDTH) {
                            column = 1;
                        column = 1;
                        }
                     }
                     }
                    if (column === 1) {
                        form += '</tr><tr>';
                    }
                    form += '\n<td' + __TDOPT + '>' + __ELEMENT.replace('|', '</td><td>') + '</td>';
                 }
                 }
                if (column === 1) {
                    form += '</tr><tr>';
                }
                form += '\n<td' + __TDOPT + '>' + __ELEMENT.replace('|', '</td><td>') + '</td>';
             }
             }
         }
         }
Zeile 3.143: Zeile 2.735:
                                           if (__PARAM !== undefined) {
                                           if (__PARAM !== undefined) {
                                               // Klassifizierte Optionen umbenennen...
                                               // Klassifizierte Optionen umbenennen...
                                               return renameOptions(this.optSet, this.optSelect, __PARAM, this.renameFun);
                                               renameOptions(this.optSet, this.optSelect, __PARAM, this.renameFun);
                                          } else {
                                              return Promise.resolve();
                                           }
                                           }
                                       },
                                       },
                     'deleteOptions' : function(ignList) {
                     'deleteOptions' : function() {
                                          const __OPTSELECT = addProps([], this.optSelect, null, ignList);
                                           return deleteOptions(this.optSet, this.optSelect, true, true);
 
                                           return deleteOptions(this.optSet, __OPTSELECT, true, true);
                                       }
                                       }
                 });
                 } );


// ==================== Ende Abschnitt fuer Klasse Classification ====================
// ==================== Ende Abschnitt fuer Klasse Classification ====================
Zeile 3.180: Zeile 2.768:
                                           }
                                           }
                                       }
                                       }
                 });
                 } );


// ==================== Ende Abschnitt fuer Klasse TeamClassification ====================
// ==================== Ende Abschnitt fuer Klasse TeamClassification ====================
Zeile 3.187: Zeile 2.775:


// Klasse fuer Teamdaten
// Klasse fuer Teamdaten
function Team(team, land, liga) {
    'use strict';


/*class*/ function Team /*{
     this.Team = team;
     constructor*/(team, land, liga, teamId) {
    this.Land = land;
        'use strict';
    this.Liga = liga;
 
    this.LdNr = getLandNr(land);
        this.Team = team;
    this.LgNr = getLigaNr(liga);
        this.Land = land;
}
        this.Liga = liga;
        this.TmNr = (teamId || 0);
        this.LdNr = getLandNr(land);
        this.LgNr = getLigaNr(liga);
    }
//}


Class.define(Team, Object, {
Class.define(Team, Object, {
Zeile 3.206: Zeile 2.790:
                                         'Liga' : true,
                                         'Liga' : true,
                                         'Land' : true,
                                         'Land' : true,
                                        'TmNr' : true,
                                         'LdNr' : true,
                                         'LdNr' : true,
                                         'LgNr' : true
                                         'LgNr' : true
                                     }
                                     }
                 });
                 } );


// ==================== Ende Abschnitt fuer Klasse Team ====================
// ==================== Ende Abschnitt fuer Klasse Team ====================


// ==================== Abschnitt fuer Klasse Verein ====================
// ==================== Spezialisierter Abschnitt fuer Optionen ====================
 
// Klasse fuer Vereinsdaten
 
/*class*/ function Verein /*extends Team {
    constructor*/(team, land, liga, teamId, manager, flags) {
        'use strict';
 
        Team.call(this, team, land, liga, teamId);
 
        this.Manager = manager;
        this.Flags = (flags || []);
    }
//}
 
Class.define(Verein, Team, {
                    '__TEAMITEMS' : {  // Items, die in Verein als Teamdaten gesetzt werden...
                                        'Team'    : true,
                                        'Liga'    : true,
                                        'Land'    : true,
                                        'TmNr'    : true,
                                        'LdNr'    : true,
                                        'LgNr'    : true,
                                        'Manager' : true,
                                        'Flags'  : true
                                    }
                });
 
// ==================== Ende Abschnitt fuer Klasse Verein ====================
 
// ==================== Spezialisierter Abschnitt fuer Optionen ====================


// Gesetzte Optionen (wird von initOptions() angelegt und von loadOptions() gefuellt):
// Gesetzte Optionen (wird von initOptions() angelegt und von loadOptions() gefuellt):
Zeile 3.260: Zeile 2.813:
// Gibt die Teamdaten zurueck und aktualisiert sie ggfs. in der Option
// Gibt die Teamdaten zurueck und aktualisiert sie ggfs. in der Option
// optSet: Platz fuer die gesetzten Optionen
// optSet: Platz fuer die gesetzten Optionen
// teamParams: Dynamisch ermittelte Teamdaten ('Team', 'Liga', 'Land', 'TmNr', 'LdNr' und 'LgNr')
// teamParams: Dynamisch ermittelte Teamdaten ('Team', 'Liga', 'Land', 'LdNr' und 'LgNr')
// myTeam: Objekt fuer die Teamdaten
// myTeam: Objekt fuer die Teamdaten
// return Die Teamdaten oder undefined bei Fehler
// return Die Teamdaten oder undefined bei Fehler
Zeile 3.267: Zeile 2.820:
         addProps(myTeam, teamParams, myTeam.__TEAMITEMS);
         addProps(myTeam, teamParams, myTeam.__TEAMITEMS);
         __LOG[2]("Ermittelt: " + safeStringify(myTeam));
         __LOG[2]("Ermittelt: " + safeStringify(myTeam));
         // ... und abspeichern, falls erweunscht...
         // ... und abspeichern...
         if (optSet && optSet.team) {
         setOpt(optSet.team, myTeam, false);
            setOpt(optSet.team, myTeam, false);
        }
     } else {
     } else {
         const __TEAM = ((optSet && optSet.team) ? getOptValue(optSet.team) : undefined);  // Gespeicherte Parameter
         const __TEAM = getOptValue(optSet.team);  // Gespeicherte Parameter


         if ((__TEAM !== undefined) && (__TEAM.Land !== undefined)) {
         if ((__TEAM !== undefined) && (__TEAM.Land !== undefined)) {
Zeile 3.278: Zeile 2.829:
             __LOG[2]("Gespeichert: " + safeStringify(myTeam));
             __LOG[2]("Gespeichert: " + safeStringify(myTeam));
         } else {
         } else {
             __LOG[6]("Team nicht ermittelt: " + safeStringify(__TEAM));
             __LOG[1]("Unbekannt: " + safeStringify(__TEAM));
         }
         }
     }
     }


    //return ((myTeam.length > 0) ? myTeam : undefined);
     return myTeam;
     return myTeam;
}
}
Zeile 3.296: Zeile 2.848:
// 'formWidth': Anzahl der Elemente pro Zeile
// 'formWidth': Anzahl der Elemente pro Zeile
// 'formBreak': Elementnummer des ersten Zeilenumbruchs
// 'formBreak': Elementnummer des ersten Zeilenumbruchs
// return Promise auf gefuelltes Objekt mit den gesetzten Optionen
// return Gefuelltes Objekt mit den gesetzten Optionen
function buildOptions(optConfig, optSet = undefined, optParams = { 'hideMenu' : false }) {
function buildOptions(optConfig, optSet = undefined, optParams = { 'hideMenu' : false }) {
     // Klassifikation ueber Land und Liga des Teams...
     // Klassifikation ueber Land und Liga des Teams...
Zeile 3.302: Zeile 2.854:
     __TEAMCLASS.teamParams = optParams.teamParams;  // Ermittelte Parameter
     __TEAMCLASS.teamParams = optParams.teamParams;  // Ermittelte Parameter


     return startOptions(optConfig, optSet, __TEAMCLASS).then(
     optSet = startOptions(optConfig, optSet, __TEAMCLASS);
                optSet => showOptions(optSet, optParams),
 
                defaultCatch);
    showOptions(optSet, optParams);
 
    return optSet;
}
}


Zeile 3.343: Zeile 2.897:
                             this.uri.setQueryPar('landauswahl', team.LdNr);
                             this.uri.setQueryPar('landauswahl', team.LdNr);
                             this.uri.setQueryPar('ligaauswahl', team.LgNr);
                             this.uri.setQueryPar('ligaauswahl', team.LgNr);
                            this.uri.setQueryPar('hl',          team.TmNr);                        },
                        },
         'setPage'      : function(page, label) {
         'setPage'      : function(page, label) {
                             this.uri.home();
                             this.uri.home();
Zeile 3.405: Zeile 2.959:
         'saison'      : saison,
         'saison'      : saison,
         'ZAT'          : 0,
         'ZAT'          : 0,
         'gameType'    : 'spielfrei',
         'gameType'    : "spielfrei",
         'heim'        : true,
         'heim'        : true,
         'gegner'      : "",
         'gegner'      : "",
Zeile 3.502: Zeile 3.056:
     const __LINK = new RundenLink(currZAT.saison, __TEAMCLASS.team);
     const __LINK = new RundenLink(currZAT.saison, __TEAMCLASS.team);


     if (currZAT.gameType === 'Liga') {
     if (currZAT.gameType === "Liga") {
         if (currZAT.ZAT < 70) {
         if (currZAT.ZAT < 70) {
             __LINK.setRunde('stauswahl', currZAT.ligaSpieltag);
             __LINK.setRunde("stauswahl", currZAT.ligaSpieltag);
             __LINK.setPage('ls', __LINK.runde + ". Spieltag");
             __LINK.setPage("ls", __LINK.runde + ". Spieltag");
         } else {
         } else {
             __LINK.setLabel("Relegation");
             __LINK.setLabel("Relegation");
         }
         }
     } else if (currZAT.gameType === 'LP') {
     } else if (currZAT.gameType === "LP") {
         __LINK.setRunde('stauswahl', currZAT.pokalRunde);
         __LINK.setRunde("stauswahl", currZAT.pokalRunde);
         __LINK.setPage('lp', __POKALRUNDEN[__LINK.runde]);
         __LINK.setPage("lp", __POKALRUNDEN[__LINK.runde]);
     } else if ((currZAT.gameType === 'OSCQ') || (currZAT.gameType === 'OSEQ')) {
     } else if ((currZAT.gameType === "OSCQ") || (currZAT.gameType === "OSEQ")) {
         __LINK.setRunde('runde', currZAT.euroRunde);
         __LINK.setRunde("runde", currZAT.euroRunde);
         __LINK.setPage(((currZAT.gameType === 'OSCQ') ? 'oscq' : 'oseq'), __QUALIRUNDEN[__LINK.runde] + __HINRUECK[currZAT.hinRueck]);
         __LINK.setPage(((currZAT.gameType === "OSCQ") ? "oscq" : "oseq"), __QUALIRUNDEN[__LINK.runde] + __HINRUECK[currZAT.hinRueck]);
     } else if (currZAT.gameType === 'OSC') {
     } else if (currZAT.gameType === "OSC") {
         if (currZAT.euroRunde < 9) {
         if (currZAT.euroRunde < 9) {
             const __GRUPPENPHASE = ((currZAT.euroRunde < 6) ? "HR-Grp. " : "ZR-Grp. ");
             const __GRUPPENPHASE = ((currZAT.euroRunde < 6) ? "HR-Grp. " : "ZR-Grp. ");


             __LINK.setRunde("", (currZAT.euroRunde % 3) * 2 + 1 + currZAT.hinRueck);
             __LINK.setRunde("", (currZAT.euroRunde % 3) * 2 + 1 + currZAT.hinRueck);
             __LINK.setPage(((currZAT.euroRunde < 6) ? 'oschr' : 'osczr'), __GRUPPENPHASE + "Spiel " + __LINK.runde);
             __LINK.setPage(((currZAT.euroRunde < 6) ? "oschr" : "osczr"), __GRUPPENPHASE + "Spiel " + __LINK.runde);
         } else {
         } else {
             __LINK.setPage('oscfr', __OSCRUNDEN[currZAT.euroRunde - 8] + __HINRUECK[currZAT.hinRueck]);
             __LINK.setPage("oscfr", __OSCRUNDEN[currZAT.euroRunde - 8] + __HINRUECK[currZAT.hinRueck]);
         }
         }
     } else if (currZAT.gameType === 'OSE') {
     } else if (currZAT.gameType === "OSE") {
         __LINK.setRunde('runde', currZAT.euroRunde - 3);
         __LINK.setRunde("runde", currZAT.euroRunde - 3);
         __LINK.setPage('ose', __OSERUNDEN[__LINK.runde] + __HINRUECK[currZAT.hinRueck]);
         __LINK.setPage("ose", __OSERUNDEN[__LINK.runde] + __HINRUECK[currZAT.hinRueck]);
    } else if (currZAT.gameType === 'Supercup') {
        __LINK.setRunde("", 1);
        __LINK.setPage('supercup', currZAT.gameType);
     } else {
     } else {
         __LINK.setLabel();  // irgendwie besser lesbar! ("Friendly" bzw. "spielfrei"/"Frei"/"reserviert")
         __LINK.setLabel();  // irgendwie besser lesbar! ("Friendly" bzw. "spielfrei"/"Frei"/"reserviert")
Zeile 3.541: Zeile 3.092:
// ==================== Abschnitt fuer interne IDs auf den Seiten ====================
// ==================== Abschnitt fuer interne IDs auf den Seiten ====================


const __GAMETYPENRN = {    // "Blind FSS gesucht!"
const __GAMETYPES = {    // "Blind FSS gesucht!"
         'unbekannt'  : -1,
         'unbekannt'  : -1,
         'reserviert' :  0,
         "reserviert" :  0,
         'Frei'       :  0,
         "Frei"       :  0,
         'spielfrei' :  0,
         "spielfrei" :  0,
         'Friendly'   :  1,
         "Friendly"   :  1,
         'Liga'       :  2,
         "Liga"       :  2,
         'LP'         :  3,
         "LP"         :  3,
         'OSEQ'       :  4,
         "OSEQ"       :  4,
         'OSE'       :  5,
         "OSE"       :  5,
         'OSCQ'       :  6,
         "OSCQ"       :  6,
         'OSC'       :  7,
         "OSC"       :  7
        'Supercup'  : 10
     };
     };
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);


const __LIGANRN = {
const __LIGANRN = {
Zeile 3.582: Zeile 3.116:
         '3. Liga D'  :  7
         '3. Liga D'  :  7
     };
     };
const __LIGATYPES = reverseMapping(__LIGANRN);


const __LANDNRN = {
const __LANDNRN = {
Zeile 3.639: Zeile 3.172:
         'Zypern'                :  38
         'Zypern'                :  38
     };
     };
const __LAENDER = reverseMapping(__LANDNRN);
const __TLALAND = {
        undefined : 'unbekannt',
        'ALB'    : 'Albanien',
        'AND'    : 'Andorra',
        'ARM'    : 'Armenien',
        'AZE'    : 'Aserbaidschan',
        'BEL'    : 'Belgien',
        'BIH'    : 'Bosnien-Herzegowina',
        'BUL'    : 'Bulgarien',
        'DEN'    : 'D\xE4nemark',
        'GER'    : 'Deutschland',
        'ENG'    : 'England',
        'EST'    : 'Estland',
        'FRO'    : 'Far\xF6er',
        'FIN'    : 'Finnland',
        'FRA'    : 'Frankreich',
        'GEO'    : 'Georgien',
        'GRE'    : 'Griechenland',
        'IRL'    : 'Irland',
        'ISL'    : 'Island',
        'ISR'    : 'Israel',
        'ITA'    : 'Italien',
        'KAZ'    : 'Kasachstan',
        'CRO'    : 'Kroatien',
        'LVA'    : 'Lettland',
        'LIE'    : 'Liechtenstein',
        '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 ====================
// ==================== Abschnitt fuer Daten des Spielplans ====================
Zeile 3.702: Zeile 3.177:
// Gibt die ID fuer den Namen eines Wettbewerbs zurueck
// Gibt die ID fuer den Namen eines Wettbewerbs zurueck
// gameType: Name des Wettbewerbs eines Spiels
// gameType: Name des Wettbewerbs eines Spiels
// defValue: Default-Wert
// return OS2-ID fuer den Spieltyp (1 bis 7), 0 fuer spielfrei/Frei/reserviert, -1 fuer ungueltig
// return OS2-ID fuer den Spieltyp (1 bis 7 oder 10), 0 fuer "spielfrei"/"Frei"/"reserviert", -1 fuer ungueltig
function getGameTypeID(gameType) {
function getGameTypeID(gameType, defValue = __GAMETYPENRN.unbekannt) {
     return getValue(__GAMETYPES[gameType], __GAMETYPES.unbekannt);
     return getValue(__GAMETYPENRN[gameType], defValue);
}
 
// Gibt den Namen eines Wettbewerbs zurueck
// 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
// gameType: Name des Wettbewerbs eines Spiels
// return Normalerweise den uebergebenen Parameter, in Einzelfaellen eine Kurzversion
function getGameTypeAlias(gameType) {
    return getValue(__GAMETYPEALIASES[gameType], getValue(gameType, __GAMETYPEALIASES.unbekannt));
}
 
// Gibt den Namen des Landes mit dem uebergebenen Kuerzel (TLA) zurueck.
// tla: Kuerzel (TLA) des Landes
// defValue: Default-Wert
// return Name des Landes, 'unbekannt' fuer undefined
function getLandName(tla, defValue = __TLALAND[undefined]) {
    return getValue(__TLALAND[tla], defValue);
}
}


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


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


// Kehrt das Mapping eines Objekts um und liefert ein neues Objekt zurueck.
// Ermittelt den Spielgegner aus einer Tabellenzelle und liefert den Namen zurueck
// obj: Objekt mit key => value
// cell: Tabellenzelle mit dem Namen des Gegners
// convFun: Konvertierfunktion fuer die Werte
// return Der Name des Gegners
// return Neues Objekt mit value => key (doppelte value-Werte fallen heraus!)
function getGegnerFromCell(cell) {
function reverseMapping(obj, convFun) {
     const __GEGNER = cell.textContent;
     if (! obj) {
    const __POS = __GEGNER.indexOf(" (");
        return obj;
    }


    const __RET = { };
     if (~ __POS) {
 
    for (let key in obj) {
        const __VALUE = obj[key];
 
        __RET[__VALUE] = (convFun ? convFun(key) : key);
    }
 
    return __RET;
}
 
// ==================== Abschnitt fuer sonstige Parameter ====================
 
// Ermittelt den Spielgegner aus einer Tabellenzelle und liefert den Namen zurueck
// cell: Tabellenzelle mit dem Namen des Gegners
// return Der Name des Gegners
function getGegnerFromCell(cell) {
    const __GEGNER = cell.textContent;
    const __POS = __GEGNER.indexOf(" (");
 
     if (~ __POS) {
         return __GEGNER.substr(0, __POS);
         return __GEGNER.substr(0, __POS);
     } else {
     } else {
Zeile 3.814: Zeile 3.241:
// currZAT: Enthaelt den Spielplanzeiger auf den aktuellen ZAT
// currZAT: Enthaelt den Spielplanzeiger auf den aktuellen ZAT
// cell: Tabellenzelle mit Eintrag "2 : 1"
// cell: Tabellenzelle mit Eintrag "2 : 1"
// return Modifizierter Spielplanzeiger
function setErgebnisFromCell(currZAT, cell) {
function setErgebnisFromCell(currZAT, cell) {
     const __ERGEBNIS = getErgebnisFromCell(cell);
     const __ERGEBNIS = getErgebnisFromCell(cell);
Zeile 3.825: Zeile 3.251:
         currZAT.gAga = -1;
         currZAT.gAga = -1;
     }
     }
    return currZAT;
}
}


Zeile 3.836: Zeile 3.260:


     currZAT.gameType = __SPIELART[0];
     currZAT.gameType = __SPIELART[0];
     currZAT.heim    = (__SPIELART.length < 2) || (__SPIELART[1] === 'Heim');
     currZAT.heim    = (__SPIELART.length < 2) || (__SPIELART[1] === "Heim");
}
}


Zeile 3.848: Zeile 3.272:
     let ret = "";
     let ret = "";


     if (cell.textContent !== 'Vorschau') {  // Nur falls Link nicht bereits vorhanden
     if (cell.textContent !== "Vorschau") {  // Nur falls Link nicht bereits vorhanden
         if (__GAMETYPEID > 1) {              // nicht moeglich fuer "Friendly" bzw. "spielfrei"/"Frei"/"reserviert"
         if (__GAMETYPEID > 1) {              // nicht moeglich fuer "Friendly" bzw. "spielfrei"/"Frei"/"reserviert"
             const __SEARCHFUN = ":os_bericht(";
             const __SEARCHFUN = ":os_bericht(";
Zeile 3.878: Zeile 3.302:


const __TEAMSEARCHHAUPT = {  // Parameter zum Team "<b>Willkommen im Managerb&uuml;ro von TEAM</b><br>LIGA LAND<a href=..."
const __TEAMSEARCHHAUPT = {  // Parameter zum Team "<b>Willkommen im Managerb&uuml;ro von TEAM</b><br>LIGA LAND<a href=..."
        'Tabelle'  : 1,
         'Zeile' : 0,
         'Zeile'     : 0,
         'Spalte' : 1,
         'Spalte'   : 1,
         'start' : " von ",
         'start'     : " von ",
         'middle' : "</b><br>",
         'middle'   : "</b><br>",
         'liga'   : ". Liga",
         'liga'     : ". Liga",
         'land'   : ' ',
         'land'     : ' ',
         'end'   : "<a href="
         'end'       : "<a href="
     };
     };


const __TEAMSEARCHTEAM = {  // Parameter zum Team "<b>TEAM - LIGA <a href=...>LAND</a></b>"
const __TEAMSEARCHTEAM = {  // Parameter zum Team "<b>TEAM - LIGA <a href=...>LAND</a></b>"
        'Tabelle'  : 1,
         'Zeile' : 0,
         'Zeile'     : 0,
         'Spalte' : 0,
         'Spalte'   : 0,
         'start' : "<b>",
         'start'     : "<b>",
         'middle' : " - ",
         'middle'   : " - ",
         'liga'   : ". Liga",
         'liga'     : ". Liga",
         'land'   : 'target="_blank">',
         'land'     : 'target="_blank">',
         'end'    : "</a></b>"
         'end'      : "</a></b>"
    };
 
const __TEAMIDSEARCHHAUPT = {  // Parameter zur Team-ID "<b>Deine Spiele in</b>...<a href="livegame/index.php?spiele=TEAMID,0">LIVEGAME</a>"
        'Tabelle'  : 0,
        'Zeile'    : 6,
        'Spalte'    : 0,
        'start'    : '<a href="livegame/index.php?spiele=',
        'end'      : ',0">LIVEGAME</a>'
    };
 
const __TEAMIDSEARCHTEAM = {  // Parameter zur Team-ID "<b>Deine Spiele in</b>...<a href="livegame/index.php?spiele=TEAMID,0">LIVEGAME</a>"
        'Tabelle'  : 0,
        'Zeile'    : 1,
        'Spalte'    : 1,
        'start'    : '<a hspace="20" href="javascript:tabellenplatz(',
        'end'      : ')">Tabellenpl\xE4tze</a>'
     };
     };


// Ermittelt, wie das eigene Team heisst und aus welchem Land bzw. Liga es kommt (zur Unterscheidung von Erst- und Zweitteam)
// Ermittelt, wie das eigene Team heisst und aus welchem Land bzw. Liga es kommt (zur Unterscheidung von Erst- und Zweitteam)
// teamSearch: Muster fuer die Suche nach Team, die Eintraege fuer 'start', 'middle', 'liga', 'land' und 'end' enthaelt, ausserdem die
// cell: Tabellenzelle mit den Parametern zum Team "startTEAMmiddleLIGA...landLANDend", LIGA = "#liga[ (A|B|C|D)]"
//              Adresse der 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
// teamIdSearch: Muster fuer die Suche nach Team-ID, die Eintraege fuer 'start' und 'end' enthaelt, ausserdem die
// return Im Beispiel { 'Team' : "TEAM", 'Liga' : "LIGA", 'Land' : "LAND", 'LdNr' : LAND-NUMMER, 'LgNr' : LIGA-NUMMER },
//              Adresse der Tabellenzelle mit den Parametern zur Team-ID "startTEAMIDend"
//        z.B. { 'Team' : "Choromonets Odessa", 'Liga' : "1. Liga", 'Land' : "Ukraine", 'LdNr' : 20, 'LgNr' : 1 }
// doc: Optionale Angabe des Dokuments, in dem die Tabelle gesucht wird  (Default: document)
function getTeamParamsFromTable(table, teamSearch = undefined) {
// return Im Beispiel { 'Team' : "TEAM", 'Liga' : "LIGA", 'Land' : "LAND", 'TmNr' : TEAMID, 'LdNr' : LAND-NUMMER, 'LgNr' : LIGA-NUMMER },
//        z.B. { 'Team' : "Choromonets Odessa", 'Liga' : "1. Liga", 'Land' : "Ukraine", 'TmNr' : 930, 'LdNr' : 20, 'LgNr' : 1 }
function getTeamParamsFromTable(teamSearch, teamIdSearch, doc = document) {
    // Ermittlung von Team, Liga und Land...
     const __TEAMSEARCH  = getValue(teamSearch, __TEAMSEARCHHAUPT);
     const __TEAMSEARCH  = getValue(teamSearch, __TEAMSEARCHHAUPT);
    const __TEAMTABLE    = getTable(getValue(__TEAMSEARCH.Tabelle, 1), 'table', doc);
     const __TEAMCELLROW  = getValue(__TEAMSEARCH.Zeile, 0);
     const __TEAMCELLROW  = getValue(__TEAMSEARCH.Zeile, 0);
     const __TEAMCELLCOL  = getValue(__TEAMSEARCH.Spalte, 0);
     const __TEAMCELLCOL  = getValue(__TEAMSEARCH.Spalte, 0);
     const __TEAMCELLSTR  = (__TEAMTABLE === undefined) ? "" : __TEAMTABLE.rows[__TEAMCELLROW].cells[__TEAMCELLCOL].innerHTML;
     const __TEAMCELLSTR  = (table === undefined) ? "" : table.rows[__TEAMCELLROW].cells[__TEAMCELLCOL].innerHTML;
     const __SEARCHSTART  = __TEAMSEARCH.start;
     const __SEARCHSTART  = __TEAMSEARCH.start;
     const __SEARCHMIDDLE = __TEAMSEARCH.middle;
     const __SEARCHMIDDLE = __TEAMSEARCH.middle;
Zeile 3.942: Zeile 3.343:
     const __INDEXMIDDLE = teamParams.indexOf(__SEARCHMIDDLE);
     const __INDEXMIDDLE = teamParams.indexOf(__SEARCHMIDDLE);


     let land = ((~ __INDEXLIGA) ? teamParams.substring(__INDEXLIGA + __SEARCHLIGA.length) : undefined);
     let land = (~ __INDEXLIGA) ? teamParams.substring(__INDEXLIGA + __SEARCHLIGA.length) : undefined;
     const __TEAMNAME = ((~ __INDEXMIDDLE) ? teamParams.substring(0, __INDEXMIDDLE) : undefined);
     const __TEAMNAME = (~ __INDEXMIDDLE) ? teamParams.substring(0, __INDEXMIDDLE) : undefined;
     let liga = (((~ __INDEXLIGA) && (~ __INDEXMIDDLE)) ? teamParams.substring(__INDEXMIDDLE + __SEARCHMIDDLE.length) : undefined);
     let liga = ((~ __INDEXLIGA) && (~ __INDEXMIDDLE)) ? teamParams.substring(__INDEXMIDDLE + __SEARCHMIDDLE.length) : undefined;


     if (land !== undefined) {
     if (land !== undefined) {
Zeile 3.959: Zeile 3.360:
     }
     }


    // Ermittlung der Team-ID (indirekt ueber den Livegame- bzw. Tabellenplatz-Link)...
     const __TEAM = new Team(__TEAMNAME, land, liga);
    const __TEAMIDSEARCH  = getValue(teamIdSearch, __TEAMIDSEARCHHAUPT);
    const __TEAMIDTABLE    = getTable(getValue(__TEAMIDSEARCH.Tabelle, 0), 'table', doc);
    const __TEAMIDCELLROW  = getValue(__TEAMIDSEARCH.Zeile, 6);
    const __TEAMIDCELLCOL  = getValue(__TEAMIDSEARCH.Spalte, 0);
    const __TEAMIDCELLSTR  = (__TEAMIDTABLE === undefined) ? "" : __TEAMIDTABLE.rows[__TEAMIDCELLROW].cells[__TEAMIDCELLCOL].innerHTML;
    const __SEARCHIDSTART  = __TEAMIDSEARCH.start;
    const __SEARCHIDEND    = __TEAMIDSEARCH.end;
    const __INDEXIDSTART  = __TEAMIDCELLSTR.indexOf(__SEARCHIDSTART);
    const __INDEXIDEND    = __TEAMIDCELLSTR.indexOf(__SEARCHIDEND);
    const __TEAMIDSTR      = __TEAMIDCELLSTR.substring(__INDEXIDSTART + __SEARCHIDSTART.length, __INDEXIDEND);
    const __TEAMID        = Number.parseInt(__TEAMIDSTR, 10);
 
     const __TEAM = new Team(__TEAMNAME, land, liga, __TEAMID);


     return __TEAM;
     return __TEAM;
Zeile 4.028: Zeile 3.416:


// Spult die Daten um anzZAT ZATs vor und schreibt Parameter
// Spult die Daten um anzZAT ZATs vor und schreibt Parameter
// anhand des Spielplans fort. Also Spieltag, Runde, etc.
// anhand des Spielplans fort. Also Spieltag, Runde, etc.
// row: Zeile mit den Daten zum Spiel (Spielart, Gegner)
// row: Zeile mit den Daten zum Spiel (Spielart, Gegner)
// currZAT: Enthaelt den Spielplanzeiger auf den aktuellen ZAT
// currZAT: Enthaelt den Spielplanzeiger auf den aktuellen ZAT
// anzZAT: Anzahl der ZAT, um die vorgespult wird
// anzZAT: Anzahl der ZAT, um die vorgespult wird
// bilanz: Angabe, ob Bilanz-Link eingefuegt werden oll
// bilanz: Angabe, ob Bilanz-Link eingefuegt werden oll
function addZusatz(row, currZAT, anzZAT = 1, bilanz = false) {
function addZusatz(row, currZAT, anzZAT = 1, bilanz = false) {
     const __ROW = getValue(row, { });
     const __ROW = getValue(row, { });
     const __CELLS = __ROW.cells;
     const __CELLS = __ROW.cells;
     const __COLUMNINDEX = {
     const __COLUMNINDEX = {
             'Lbl' : 0,
             'Lbl' : 0,
             'Art' : 1,
             'Art' : 1,
             'Geg' : 2,
             'Geg' : 2,
             'Ber' : 2,
             'Ber' : 2,
             'Zus' : 3
             'Zus' : 3
         };
         };
 
    if (__CELLS) {
        setGegnerFromCell(currZAT, __CELLS[__COLUMNINDEX.Geg]);
        setSpielArtFromCell(currZAT, __CELLS[__COLUMNINDEX.Art]);
        if (bilanz) {
            addBilanzLinkToCell(__CELLS[__COLUMNINDEX.Ber], currZAT.gameType, "(Bilanz)");
        }
        incZAT(currZAT, anzZAT);
        appendHTML(__ROW, "&amp;nbsp;" + getZusatz(currZAT, true));
        __CELLS[__COLUMNINDEX.Zus].className = __CELLS[__COLUMNINDEX.Art].className;
    }
}
 
// ==================== Hauptprogramm ====================
 
// Verarbeitet Ansicht "Haupt" (Managerbuero)
function procHaupt() {
    const __TEAMPARAMS = getTeamParamsFromTable(getTable(1), __TEAMSEARCHHAUPT);  // Link mit Team, Liga, Land...
 
    buildOptions(__OPTCONFIG, __OPTSET, {
                    'teamParams' : __TEAMPARAMS,
                    'menuAnchor' : getTable(1, "div"),
                    'hideForm'  : {
                                        'team'        : true
                                    }
                });
 
    const __ZAT = firstZAT(getOptValue(__OPTSET.saison), getOptValue(__OPTSET.ligaSize));
    const __ZATCELL = getProp(getProp(getRows(0), 2), 'cells', { })[0];
    const __NEXTZAT = getZATNrFromCell(__ZATCELL);  // "Der naechste ZAT ist ZAT xx und ..."
    const __CURRZAT = __NEXTZAT - 1;


     if (__CELLS) {
     addZusatz(getProp(getRows(2), 0), __ZAT, __CURRZAT, true);   // "Dein letztes Spiel:" (+ __CURRZAT)
        setGegnerFromCell(currZAT, __CELLS[__COLUMNINDEX.Geg]);
    addZusatz(getProp(getRows(3), 0), __ZAT);                     // "Dein naechstes Spiel:" (+ 1 ZAT)
        setSpielArtFromCell(currZAT, __CELLS[__COLUMNINDEX.Art]);
        if (bilanz) {
            addBilanzLinkToCell(__CELLS[__COLUMNINDEX.Ber], currZAT.gameType, "(Bilanz)");
        }
        incZAT(currZAT, anzZAT);
        appendHTML(__ROW, "&nbsp;" + getZusatz(currZAT, true));
        __CELLS[__COLUMNINDEX.Zus].className = __CELLS[__COLUMNINDEX.Art].className;
    }
}
}


// ==================== Hauptprogramm ====================
try {
 
     procHaupt();
// Verarbeitet Ansicht "Haupt" (Managerbuero)
} catch (ex) {
function procHaupt() {
    showAlert('[' + ex.lineNumber + "] " + __DBMOD.Name, ex.message, ex);
     const __TEAMPARAMS = getTeamParamsFromTable(__TEAMSEARCHHAUPT, __TEAMIDSEARCHHAUPT);
} finally {
 
    __LOG[2]("SCRIPT END");
    return buildOptions(__OPTCONFIG, __OPTSET, {
                            'teamParams' : __TEAMPARAMS,
                            'menuAnchor' : getTable(1, 'div'),
                            'hideForm'  : {
                                              'team'        : true
                                          }
                        }).then(optSet => {
            const __ZAT = firstZAT(getOptValue(__OPTSET.saison), getOptValue(__OPTSET.ligaSize));
            const __ZATCELL = getProp(getProp(getRows(0), 2), 'cells', { })[0];
            const __NEXTZAT = getZATNrFromCell(__ZATCELL);  // "Der naechste ZAT ist ZAT xx und ..."
            const __CURRZAT = __NEXTZAT - 1;
 
            addZusatz(getProp(getRows(2), 0), __ZAT, __CURRZAT, true);    // "Dein letztes Spiel:" (+ __CURRZAT)
            addZusatz(getProp(getRows(3), 0), __ZAT);                    // "Dein naechstes Spiel:" (+ 1 ZAT)
        });
}
}
(() => {
    (async () => {
        try {
            await procHaupt().catch(defaultCatch);
            return 'OK';
        } catch (ex) {
            return defaultCatch(ex);
        }
    })().then(rc => {
            __LOG[1]('SCRIPT END', __DBMOD.Name, '(' + rc + ')');
        })
})();


// *** EOF ***
// *** EOF ***
</pre>
</pre>

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)