User:PerfektesChaos/js/tableXpander/d.js

/// tableXpander.js /// 2023-04-19 PerfektesChaos@de.wikipedia /// Documentation: w:en:User:PerfektesChaos/js/tableXpander /// Fingerprint:   #0#0# /// @license: CC-by-sa/4.0 GPLv3 /// /* global window:false                                                */ /* jshint forin:false, bitwise:true, curly:true, eqeqeq:true, latedef:true, laxbreak:true, nocomma:true, strict:true, undef:true, unused:true          */ ( function ( mw, $ ) {  "use strict";   var Version   = -2.2,       Signature = "tableXpander",       API       = { Api: false },       PAGE      = { show:      Signature + "@PerfektesChaos",                     sign:      "|}===={|",                     support:   "https://en.wikipedia.org/wiki/"                                + "Special:MyLanguage/"                                + "User:PerfektesChaos/js/"                                + Signature,                     $textarea: false },       CSS       = { background: "FFF8DC",                     color:      "006400" },       NUM       = { structure: "dot;comma" },       TABLE     = { },       REPO      = { };

CSS.design = { "background": "#" + CSS.background, "color":     "#" + CSS.color }; CSS.def   = { "active": { "background-color": CSS.design.background + "!important" }, "box": { "background-color": CSS.design.background, "border-color":    CSS.design.color, "border-radius":   "6px", "border-style":    "solid", "border-width":    "3px", "clear":           "both", "margin-bottom":   "2em", "margin-left":     "1%", "margin-right":    "1%", "margin-top":      "1em", "padding":         "0.5em", "width":           "95%" }, "caption": { },                  "cell": { "display":          "table-cell", "vertical-align":  "middle" }, "chosen": { "background-color": CSS.design.color, "color":           CSS.design.background, "font-weight":     "bold", "padding":         "0.1em" }, "clickable": { "color":           CSS.design.color, "text-decoration": "none" }, "clickable::link": { "color":           CSS.design.color }, "doclink": { "font-size":       "120%", "font-weight":     "bolder" }, "grouping": { "background-color": CSS.design.color, "color":           CSS.design.background, "font-weight":     "bold", "padding":         "0.3em" }, "handle": { "background-color": CSS.design.background, "border-color":    CSS.design.color, "border-radius":   "3px", "border-style":    "solid", "border-width":    "2px", "color":           CSS.design.color, "font-size":       "100%", "font-style":      "normal", "font-weight":     "normal", "padding":         "0.2em" }, "icon": { "border-radius":   "0.4em", "border-style":    "solid", "border-width":    "0.15em", "display":         "inline-block", "font-size":       "150%", "font-weight":     "bolder", "margin":          "0.5em", "padding":         "0.3em" }, "include": { "background-color": CSS.design.background }, "info": { "border-color":    CSS.design.color, "border-radius":   "3px", "border-style":    "solid", "border-width":    "1px", "font-family":     "monospace", "font-size":       "100%", "font-style":      "normal", "font-weight":     "normal", "padding-left":    "0.1em", "padding-right":   "0.1em" },                 "quit": { "color":            "#FF0000", "font-size":       "150%", "font-weight":     "700", "text-align":      "center", "vertical-align":  "middle"}, "td":  { "background-color": CSS.design.background, "color":           CSS.design.color, "font-size":       "100%", "font-style":      "normal", "font-weight":     "normal", "text-align":      "center" }, "textarea": { "background-color": CSS.design.background, "margin-bottom":   "2em", "margin-top":      "1em", "width":           "95%" }, "toggle": { "display":         "inline-block", "font-size":       "80%", "font-style":      "normal", "font-weight":     "normal", "margin":          "0.2em" }, "ul":  { "list-style-image": "none", "list-style-position": "outside", "list-style-type": "none", "margin-bottom":   "0.2em", "margin-left":     "0", "margin-right":    "0", "margin-top":      "0.2em", "padding":         "0" }, "ul > li": { "display":         "inline", "margin-right":    "0.7em", "padding":         "0" }, "ul > li::after": { "content":         " \n" }, "ul > li:last-child": { "margin-right":    "0" }, "version": { "font-size":       "80%" }, "widget": { "margin-left":     "0.8em", "margin-right":    "0.8em" } };  NUM.call      = { "#": "forward", "+": "full", "~": "fair", "%": "fraction", "?": "fruits" }; NUM.codes    = { apos:  0x27, comma: 0x2C, dot:  0x2E, nbsp: 0xA0, nnbsp: 0x202F }; NUM.entities = { apos:  0x27, nbsp: 0xA0, lrm:  false, rlm:  false, zwj:  false }; NUM.min      = 0.0001; NUM.offer    = [ "dot;comma", "comma;dot", "comma;apos", "comma;nbsp", "dot;nbsp", "comma;nnbsp", "dot;nnbsp" ]; NUM.patterns = { "dot;comma":   "0,000.00", "dot;nbsp":   "0&#x25AF;000.00", "dot;nnbsp":  "0&#x25A1;000.00", "comma;apos": "0'000,00", "comma;dot":  "0.000,00", "comma;nbsp": "0&#x25AF;000,00", "comma;nnbsp": "0&#x25A1;000,00" }; NUM.translate = { 0x2D:    45,  // - 0x2212:  45,  // typographic - 0x2B:    43,  // + 0xFF0B:  43, 0xFF0D:  45 }; NUM.seek     = NUM.structure; NUM.sep      = "."; NUM.spaces   = [ 0xA0, 0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x200B, 0x200C, 0x200D, 0x200E, 0x200F, 0x202F, 0x205F, 0x3000, 0x303F ]; NUM.starts   = "#+~%?"; NUM.variants = { apos:  [ 0x2019, 0xFF07 ], comma: [ 0xFF0C ], dot:  [ 0xFF0E ] }; NUM.zero     = [    0x30, 0x0660, 0x06F0, 0x07C0, 0x0966, 0x09E6, 0x0A66, 0x0AE6, 0x0B66, 0x0BE6, 0x0C66, 0x0CE6, 0x0D66, 0x0DE6, 0x0E50, 0x0ED0, 0x0F20, 0x102E, 0x1040, 0x1369, 0x17E0, 0x1810, 0x1946, 0x19D0, 0x1A80, 0x1A90, 0x1B50, 0x1BB0, 0x1C40, 0x1C50, 0xA620, 0xA8D0, 0xA900, 0xA9D0, 0xA9F0, 0xAA50, 0xABF0, 0xFF10, 0x1104A, 0x110D3, 0x110E6, 0x11106, 0x1110F, 0x11113, 0x1111D, 0x1112F, 0x11145, 0x1114D, 0x11165, 0x1116C, 0x11173, 0x1118E, 0x111C5, 0x111D5, 0x111DA, 0x116A6, 0x116B5, 0x116E8, 0x11E14, 0x11E2F, 0x11E8C, 0x11E95, 0x1D7F6, 0xE0030 ]; TABLE.title  = { "#": "#", "+": String.fromCharCode( 0x03A3 ),  // Sigma "~": String.fromCharCode( 0x00F8 ),  // Oslash "%": "%",                    "?": "^",                     "h": String.fromCharCode( 0x2194 ),   // <--> "v": String.fromCharCode( 0x2195 ),  // ^ "X": "X" };

//---

function fire { // Start processing // Uses: //   >  $      //    (PAGE.fire) // 2017-11-30 PerfektesChaos@de.wikipedia if ( $ ) { if ( typeof $ ===  "function" ) { $( PAGE.fire ); }     }   }   // fire

API.fail = function ( arrived, add ) { // API purging failed // Precondition: //   arrived  -- string with basic message //   add      -- object with additional information // Uses: //   window.console // 2016-08-30 PerfektesChaos@de.wikipedia if ( typeof window.console ===  "object"   &&           typeof arrived  ===  "string" ) { if ( typeof window.console.log ===  "function" ) { window.console.log( arrived ); }        if ( typeof add  ===  "object"   &&   add   &&              typeof window.console.dir  ===  "function" ) { window.console.dir( add ); }     }   };   // API.fail

API.formatnum = function { // Launch API query for number formatting // Uses: //   >< API.Api //   (API.formattednum) //   (API.fail) // 2017-05-31 PerfektesChaos@de.wikipedia var o = { action: "expandtemplates", prop:  "wikitext", text:  "1,234,567.89" }; if ( typeof API.Api !==  "object" ) { API.Api = new mw.Api; }     API.Api.get( o ).done( API.formattednum ) .fail( API.fail ); };  // API.formatnum

API.formattednum = function ( arrived ) { // API success on parsed number formatting // Precondition: //   arrived  -- JSON result of ajax query // Uses: //   NUM.formatting // 2017-05-31 PerfektesChaos@de.wikipedia if ( typeof arrived ===  "object"           &&     arrived    &&           typeof arrived.expandtemplates  ===  "object"    &&           typeof arrived.expandtemplates.wikitext  ===  "string" ) { NUM.formatting( arrived.expandtemplates.wikitext ); }  };   // API.formattednum

NUM.faculty = function ( attempt, array ) { // Precondition: //   attempt  -- character code to be checked //   access   -- Array to be checked against, or not // Postcondition: //   Returns true if character might be ignored // 2017-11-30 PerfektesChaos@de.wikipedia var i, r;     if ( array ) { for ( i = 0; i < array.length;  i++ ) { if ( array[ i ] === attempt ) { r = true; break;  // for i            } }  // for i      } return r;  };   // NUM.faculty

NUM.fair = function ( $all, $actives, $about ) { // Average of all figures // Precondition: //   $all      -- //   $actives  -- active cells //   $about    -- for result // Uses: //   >  Signature //   NUM.full // 2020-08-17 PerfektesChaos@de.wikipedia var n = $actives.length, g;     if ( n ) { g = NUM.full( $all, $actives, $about ); if ( g[ 0 ] &&  g[ 1 ] ) { n = g[ 0 ] /  g[ 1 ]; } else { n = 0; }     }      $about.text( n ); };  // NUM.fair

NUM.fetch = function ( $at ) { // Retrieve number // Precondition: //   $at  -- / // Uses: //   >  Signature //   >  NUM.reInteger //   NUM.fill // 2020-08-25 PerfektesChaos@de.wikipedia var s      = $at.data( Signature + "-parsed" ), skipped = ":hidden,[style*='visibility']", r, store, $dup; if ( s ) { if ( s !== "!" ) { r = parseInt( s, 10 ); s = false; }     } else { s = $at.data( Signature + "-raw" ); if ( ! s ) { s = $at.data( "sort-value" ); if ( s ) { $at.attr( { title: s } ); } else { if ( $at.find( skipped ).length > 1 ) { $dup = $at.clone; $dup.find( ":hidden" ).remove; s = $dup.text; } else { s = $at.text; }           }            if ( s ) { s = NUM.fill( s ); if ( s ) { if ( NUM.reInteger.test( s ) ) { store = "-parsed"; } else { store = "-raw"; }                 $at.data( Signature + store,  s ); }           }         }         if ( s ) { s = NUM.filter( s ); if ( s ) { r = parseFloat( s ); if ( isNaN( r) ) { r = false; }           }         } else { $at.data( Signature + "-parsed", "!" ); }     }      return r;   };   // NUM.fetch

NUM.figure = function ( analyze ) { // Identify digit in scripting systems // Precondition: //   analyze  -- character code // Postcondition: //   Returns code of zero, or not // Uses: //   >  NUM.zero // 2017-11-30 PerfektesChaos@de.wikipedia var i, j, r;     for ( i = 0;  i < NUM.zero.length;  i++ ) { j = NUM.zero[ i ]; if ( analyze < j ) { break;  // for i         } else { if ( analyze <=  j + 9 ) { r = j;              break;   // for i            } }     }   // for i      return r;   };   // NUM.figure

NUM.fill = function ( analyze ) { // Normalize number string // Precondition: //   analyze  -- string, with number to be parsed // Postcondition: //   Returns normalized string // Uses: //   >  Signature //   >  NUM.reInteger //   >  NUM.translate //   NUM.flat //   PAGE.flat //   NUM.foreign // 2020-08-17 PerfektesChaos@de.wikipedia var i = analyze.indexOf( "[-]" ), s = analyze, j, k, less, r;     if ( i >= 0 ) { s = s.substr( 0, i ); }     s = PAGE.flat( s ); s = NUM.flat( s ); k = NUM.translate[ s.charCodeAt( 0 ) ]; if ( k === 45 ||  k === 43 ) { less = ( k === 45 ); s   = NUM.flat( s.substr( 1 ) ); }     j = NUM.figure( s.charCodeAt( 0 ) ); if ( ! j ) { j = NUM.figure( s.charCodeAt( 1 ) ); }     if ( j ) { if ( j === 0x30 ) { r = s;        } else { r = NUM.foreign( s, j ); }        for ( i = 1;  i < r.length;  i++ ) { if ( r.charCodeAt( i ) <=  32 ) { r = r.substr( 0, i ); break;  // for i            } }  // for i         if ( less ) { r = "-" + r;        } }     return r;   };   // NUM.fill

NUM.filter = function ( attempt ) { // Parse number according to current formatting // Precondition: //   attempt  -- string // Uses: //   >  NUM.seek //   >  NUM.codes //   >  NUM.variants //   >< NUM.dec //    < NUM.omit //   NUM.faculty // 2020-07-25 PerfektesChaos@de.wikipedia var fill, i, k, large, left, less, m, r, seg, sep; if ( ! NUM.dec &&           typeof NUM.seek  ===  "string" ) { i = NUM.seek.indexOf( ";" ); if ( i > 0 ) { sep = NUM.seek.substr( 0, i ); seg = NUM.seek.substr( i + 1 ); } else { sep = NUM.seek; seg = false; }        NUM.omit = false; if ( sep  &&              typeof NUM.codes[ sep ]  ===  "number" ) { fill = function ( array, assigned ) { var i, v;              NUM[ array ] = [ NUM.codes[ assigned ] ]; if ( typeof NUM.variants[ assigned ] ===  "object" ) { v = NUM.variants[ assigned ]; for ( i = 0; i < v.length;  i++ ) { NUM[ array ].push( v[ i ] ); }  // for i               } };  // fill fill( "dec", sep ); if ( seg  &&                 typeof NUM.codes[ seg ]  ===  "number" ) { fill( "omit", seg ); }        }      }      if ( NUM.dec ) { i = 0; if ( attempt.charCodeAt( 0 ) === 0x2D ) { less = true; i   = 1; }        do {   // while k            k = attempt.charCodeAt( i ); if ( k >= 0x30 &&  k <= 0x39 ) { r = ( r || "" ) +  String.fromCharCode( k ); } else if ( NUM.faculty( k, NUM.omit ) ) { k = attempt.charCodeAt( i + 1 ); if ( ! r ||  k < 0x30  ||  k > 0x39 ) { break;  // do               } } else if ( NUM.faculty( k, NUM.dec ) ) { if ( left ) { break;  // do               } else { if ( r ) { r = r + "."; } else { k = attempt.charCodeAt( i + 1 ); if ( k === 0x45 ||  k === 0x65 ) { r = "0."; } else { break;  // do                     } }                 left = true; }           } else if ( k === 0x45  ||  k === 0x65 ) { if ( large ) { break;  // do               } else { k = attempt.charCodeAt( i + 1 ); if ( k >= 0x30 &&  k <= 0x39 ) { large = true; r    = r + "e"; } else if ( k === 0x2B ||                              k === 0x2D  ||                              k === 0x2E  ||                              k === NUM.dec[ 0 ] ) { m = k;                    k = attempt.charCodeAt( i + 2 ); if ( k >= 0x30 &&  k <= 0x39 ) { large = true; switch ( m ) { case 0x2D: r = r + "e-"; break; case 0x2E: r = r + "e0."; break; default: r = r + "e"; }  // switch m                        i++; }                 }                  if ( large ) { left = false; } else { break;  // do                  } }           } else { break;  // do            } i++; } while ( k ); if ( r && less ) { r = "-" + r;        } }     return r;   };   // NUM.filter

NUM.find = function ( assign ) { // Retrieve character name for formatting character // Precondition: //   assign  -- string with formatting character // Postcondition: //   Returns name of character // Uses: //   >  NUM.codes // 2017-11-30 PerfektesChaos@de.wikipedia var k, r, s;     if ( assign.length === 1 ) { k = assign.charCodeAt( 0 ); for ( s in NUM.codes ) { if ( NUM.codes[ s ] === k ) { r = s;              break;   // for s in NUM.codes }        }   // for s in NUM.codes }     return r;   };   // NUM.find

NUM.fire = function ( $all ) { // Requery // Precondition: //   $all  -- // Uses: //   >  Signature //   NUM.first // 2020-08-21 PerfektesChaos@de.wikipedia var $div = $all.find( "." + Signature + "-result" ), s   = $div.data( "query" ); NUM.first( $all, s, $div ); };  // NUM.fire

NUM.first = function ( $all, activity, $at ) { // Perform activity processing // Precondition: //   $all      -- //   activity  -- code of task, # + ~ % ? //   $at       -- // Uses: //   >  Signature //   >  NUM.call //   NUM.fore // 2020-08-21 PerfektesChaos@de.wikipedia var s    = NUM.call[ activity ], $code = $at.find( "code" ), $active; $code.empty; if ( activity === "?" ) { $code.hide; } else { $code.text( "0" ).show; }     NUM.fore( $all ); if ( s ) { $active = $all.find( "tbody" ) .find( "." + Signature + "-active" ) .not( "." + Signature + "-td" ); if ( $active.length ) { NUM[ s ]( $all, $active, $code ); }     }   };   // NUM.first

NUM.flat = function ( adjust ) { // Trim left // Precondition: //   adjust  -- string // Postcondition: //   Returns trimmed string // Uses: //   >  NUM.spaces // 2020-08-17 PerfektesChaos@de.wikipedia var i = 0, j, k;     do {   // while k <= 32  &&  i < adjust.length k = adjust.charCodeAt( i ); if ( k > 32 ) { for ( j = 0; j < NUM.spaces.length;  j++ ) { if ( NUM.spaces[ j ] ===  k ) { k = 32; break;  // for j               } }  // for j         } i++; } while ( k <= 32 &&  i < adjust.length ); return ( i > 1 ?  adjust.substr( i - 1 )  :  adjust  ); };  // NUM.flat

NUM.flip = function ( action, $at ) { // Number format selection // Precondition: //   action  -- event data object, or string with identifier //              .data //              [0]  -- identifier of pattern //              [1]  --  or not // Uses: //   >  NUM.$group //   >  Signature //    < NUM.seek //    < NUM.dec // 2017-11-30 PerfektesChaos@de.wikipedia var sign = Signature + "-grouping", i, seek, $li, $ul; NUM.$group.find( "." + sign ).removeClass( sign ); if ( typeof action ===  "object"           &&     action   &&           typeof action.data  ===  "object"           &&     action.data ) { seek = action.data[ 0 ]; if ( typeof action.data[ 1 ] ===  "object" ) { $li = action.data[ 1 ]; }     } else if ( typeof action  ===  "string" ) { seek = action; $li = $at; }     if ( seek ) { NUM.seek = seek; NUM.dec = false; if ( ! $li ) { $ul = NUM.$group.children( "li" ); for ( i = NUM.offer.length - 1; i >= 0;  i-- ) { $li = $ul.eq( i ); if ( NUM.offer[ i ] ===  NUM.seek ) { break;  // for i-- }           }   // for i-- }        $li.addClass( Signature + "-grouping" ); }  };   // NUM.flip

NUM.fore = function ( $all, $active, assign ) { // Equip cell(s) with indicating box and display value, or clear // Precondition: //   $all     -- or active cells / clear them all //   $active  -- active cell //   assign   -- text shown in active cell, or nil // Postcondition: //   Returns $active content, if not assign // Uses: //   >  Signature // 2020-08-27 PerfektesChaos@de.wikipedia var sign = Signature + "-info", r, $e; if ( $active ) { $e = $active.find( "." + sign ); if ( $e.length ) { $e.show; } else { $e = $( " " ); $e.addClass( sign ); $active.prepend( $e ); }        if ( assign ) { $e.empty .text( assign ); } else { r = $e.text; }     } else { $all.find( "." + sign ).hide.empty; }     return r;   };   // NUM.fore

NUM.foreign = function ( adjust, align ) { // Translate non-ASCII digits etc.     // Precondition: //   adjust  -- string with non-ASCII digits //   align   -- local zero character code // Postcondition: //   Returns name of character // 2017-11-30 PerfektesChaos@de.wikipedia var r = "", m = align - 0x30, n = align + 9, i, k;     for ( i = 0;  i < adjust.length;  i++ ) { k = adjust.charCodeAt( i ); if ( k >= align &&  k <= n ) { k -= m;        } else if ( align === 0xFF10  &&                     ( k === 0xFF0E  ||  k === 0xFF0C ) ) { k -= 0xFEE0; }        r = r + String.fromCharCode( k ); }  // for i      return r;   };   // NUM.foreign

NUM.formatting = function ( analyze ) { // Guess project formatting from project query // Precondition: //   analyze  -- string with project number formatting 1234567.89 // Uses: //   >< NUM.reSeparator //   >< NUM.reSegment //    < NUM.sep //   NUM.find //   NUM.flip //   REPO.feed // 2020-08-21 PerfektesChaos@de.wikipedia var got, s, start, struct; if ( typeof NUM.reSeparator !==  "object" ) { NUM.reSeparator = new RegExp( "^(.+)67(.+)89$" ); }     got = NUM.reSeparator.exec( analyze ); if ( got ) { start = got[ 1 ]; struct = NUM.find( got[ 2 ] ); if ( struct ) { if ( typeof NUM.codes[ struct ] ===  "number" ) { NUM.sep = String.fromCharCode( NUM.codes[ struct ] ); }           if ( typeof NUM.reSegment  !==  "object" ) { NUM.reSegment = new RegExp( "[1-4]([^2-4&]+)[2-5]" ); }           got = NUM.reSegment.exec( start ); if ( got ) { s = NUM.find( got[ 1 ] ); if ( s ) { struct = struct + ";" + s;              } }           NUM.flip( struct ); REPO.feed( "seek", struct ); }     }   };   // NUM.formatting

NUM.forward = function ( $all, $actives, $about ) { // Renumber cells // Precondition: //   $all      -- //   $actives  -- active cells //   $about    -- for result // Uses: //   NUM.fore //   TABLE.factory // 2020-08-27 PerfektesChaos@de.wikipedia var n = $actives.length, s = $about.parent.parent.data( "row" ), i, m, row, table, $t; $about.text( n ); if ( s ) { table = TABLE.factory( $all ); row  = table[ parseInt( s, 10 ) ]; m    = 0; for ( i = 0; i < row.length;  i++ ) { $t = row[ i ]; if ( $t &&  $t.is( $actives ) ) { s = NUM.fore( false, $t ); if ( ! s ) { m++; NUM.fore( false, $t, m ); }           }         }   // for i      } else { for ( i = 0; i < n;  i++ ) { NUM.fore( false, $actives.eq( i ),  i + 1 ); }  // for i      } };  // NUM.forward

NUM.fraction = function ( $all, $actives, $about ) { // Percentage of all figures // Precondition: //   $all      -- //   $actives  -- active cells //   $about    -- for result // Uses: //   >  Signature //   >  NUM.min //   >  NUM.sep //   NUM.full //   NUM.fore // 2020-08-25 PerfektesChaos@de.wikipedia var n = $actives.length, i, k, less, lesser, m, q, total, $td; if ( n ) { total = NUM.full( $all, $actives, $about ); n    = total[ 1 ]; }     if ( n ) { total = total[ 0 ]; lesser = ( total < NUM.min); if ( lesser ) { if ( total >  -1 * NUM.min ) { total = false; } else { total = -1 * total; }        }         if ( total ) { q = 1 / total; for ( i = 0; i < $actives.length;  i++ ) { $td = $actives.eq( i ); k   = NUM.fetch( $td ); if ( typeof k ===  "number" ) { less = ( k < 0 ); if ( less ) { k = -1 * k;                 } k = Math.round( 10000 * k * q ); if ( k ) { m = k % 100; k = Math.floor( k * 0.01 ); if ( less !== lesser ) { k = -1 * k;                    } if ( m ) { k = k + NUM.sep; if ( m < 10 ) { k = k + "0"; }                       k = k + m;                     } }                 NUM.fore( false,  $td,  k + "%" ); }           }   // for i         } }  };   // NUM.fraction

NUM.fruits = function ( $all, $actives, $about ) { // Renumber cells // Precondition: //   $all      -- //   $actives  -- active cells //   $about    -- for result // Uses: //   >  Signature //   >< NUM.reWhite //   >< NUM.reSpaces //   NUM.fore //   PAGE.fruit // 2020-08-21 PerfektesChaos@de.wikipedia var send = "", i, k, s, $t; $about.empty; if ( typeof NUM.reWhite !==  "object" ) { NUM.reWhite   = new RegExp( "[\t\n\r]", "g" ); NUM.reSpaces = new RegExp( " +", "g" ); }     for ( i = 0;  i < $actives.length;  i++ ) { $t = $actives.eq( i ); NUM.fore( $t ); s = $t.text; k = s.indexOf( "[-][+]" ); if ( k >= 0  &&              k  ===  s.length - 6 ) { s = s.substr( 0, k ); }        s = s.replace( NUM.reWhite, " " ) .replace( NUM.reSpaces, " " ); if ( s === " " ) { s = ""; }        if ( s.substr( 0, 1 ) === " " ) { s = s.substr( 1 ); }        if ( s.substr( s.length - 1 ) === " " ) { s = s.substr( 0, s.length - 1 ); }        send = send  +  ( send ? "\n" : "" )  +  s;      }   // for i      if ( send ) { PAGE.fruit( send ); }  };   // NUM.fruits

NUM.full = function ( $all, $actives, $about ) { // Sum of all figures // Precondition: //   $all      -- //   $actives  -- active cells //   $about    -- for result // Postcondition: //   Returns Array:   [ 0 ]   -- sum //                    [ 1 ]   -- number of summands // Uses: //   >< NUM.reInteger //   NUM.fetch // 2020-08-27 PerfektesChaos@de.wikipedia var n = $actives.length, m = n,         v = 0, got, i, k, $t; if ( typeof NUM.reEntitiy !==  "object" ) { NUM.reInteger = new RegExp( "^-?[0-9]+$" ); NUM.re0000000 = new RegExp( "^(.*\\..*)00000000[1-9]$" ); NUM.re9999999 = new RegExp( "\\.(.*99999999)([1-9])$" ); }     for ( i = 0;  i < n;  i++ ) { $t = $actives.eq( i ); k = NUM.fetch( $t ); if ( typeof k ===  "number" ) { v += k;        } else { TABLE.flipper( { data: [ $all, $t, false ] },  true ); m--; }     }   // for i      if ( v !== Math.floor( v ) ) { k = "" + v;        got = NUM.re0000000.exec( k ); if ( got ) { v = parseFloat( got[ 1 ] ); } else { got = NUM.re9999999.exec( k ); if ( got ) { k = "0."; n = got[ 1 ].length; for ( i = 0; i < n;  i++ ) { k = k + "0"; }  // for i               k   = k   +   ( 12  -  parseInt( got[ 2 ], 10 ) ); v  = v + parseFloat( k ); got = NUM.re0000000.exec( "" + v ); if ( got ) { v = parseFloat( got[ 1 ] ); }           }         }      }      $about.text( v ); return [ v, m ]; };  // NUM.full

NUM.furnish = function { // Initialize number formatting scheme // Postcondition: //   Selection has been set on project default // Uses: //   >  NUM.codes //    < NUM.sep //   REPO.fetch //   NUM.flip //   API.formatnum // 2020-08-21 PerfektesChaos@de.wikipedia var s = REPO.fetch( "seek" ), i;     if ( s ) { NUM.flip( s ); i = s.indexOf( ";" ); if ( i > 0 ) { s = s.substr( 0, i ); }        if ( typeof NUM.codes[ s ]  ===  "number" ) { NUM.sep = String.fromCharCode( NUM.codes[ s ] ); }     } else if ( mw ) { API.formatnum; }  };   // NUM.furnish

PAGE.fire = function { // Start real processing, if not yet done // Precondition: //   DOM ready // Uses: //   >  Signature //   >  PAGE.support //   >< mw      //     < PAGE.$box //   PAGE.first // 2020-08-07 PerfektesChaos@de.wikipedia var $content; if ( ! $( "#" + Signature ).length ) { PAGE.$box = $( " " ); PAGE.$box.attr( { id: Signature } ); $content = $( "#content" ); if ( ! $content.length ) { $content = $( "body" ); }        $content.prepend( PAGE.$box ); if ( ! mw  ||   typeof mw  !==  "object" ) { mw = false; }        PAGE.first; if ( mw  &&   typeof mw.hook  ===  "function" ) { mw.hook( Signature + ".ready" ).fire( PAGE.support ); }     }   };   // PAGE.fire

PAGE.first = function { // Start processing by inserting box at top of page // Uses: //   >  mw      //    >  Signature //   >  PAGE.support //   >  PAGE.sign //   >  PAGE.show //   >  CSS.def //   >  PAGE.$box //   >  Version //    < PAGE.dir //    < PAGE.ltr //    < NUM.$group //    < PAGE.id      //     < PAGE.details //   NUM.furnish //   (REPO.format) //   (NUM.flip) // 2020-08-22 PerfektesChaos@de.wikipedia var def, i, s, side, sided, single, style, $a, $icon, $li, $style, $survey, $tables, $text, $version; if ( mw && mw.loader ) { mw.loader.using( [ "mediawiki.storage" ],                         REPO.format ); }     PAGE.dir = $( "html" ).attr( "dir" )  ||  "ltr"; PAGE.ltr = ( PAGE.dir === "ltr" ); side    = ( PAGE.ltr ? "left" : "right" ); sided   = ( PAGE.ltr ? "right" : "left" ); CSS.def.caption["text-align"]  = side; CSS.def.handle["float"]        = side; CSS.def.icon["margin-"+sided]  = "1em"; CSS.def.info["float"]          = side; CSS.def.info["margin-"+sided]  = "1em"; CSS.def.toggle["float"]        = sided; CSS.def.toggle["margin-"+side] = "1em"; CSS.def.version["margin-"+side] = "4em"; $style = $( " " ); style = ""; for ( s in CSS.def ) { def  = CSS.def[ s ]; style = style + "." + Signature + "-" + s + "{\n"; for ( single in def ) { style = style + single + ":" + def[ single ] + ";\n"; }  // for single in def style = style + "}\n"; }  // for s in CSS.def $( "head" ).after( $style.text( style ) ); $a = $( "" ); $a.addClass( Signature + "-icon " + Signature + "-clickable" ) .attr( { href:  PAGE.support,                 target: "_blank" } ) .text( PAGE.sign ); $icon = $( " " ); $icon.append( $a ) .addClass( Signature + "-cell" ) .attr( { "aria-hidden": "true" } ); PAGE.$box.addClass( Signature + "-box" ); PAGE.$box.append( $icon ); $text = $( " " ); $a   = $( "" ); $a.addClass( Signature + "-doclink " + Signature + "-clickable" ) .attr( { href:  PAGE.support,                 target: "_blank" } ) .text( PAGE.show ); $text.append( $a ); $version = $( " " ); $version.addClass( Signature + "-version" ) .text( Version ); $text.append( $version ); $tables = $( "table" ).not( ":hidden" ); if ( $tables.length ) { PAGE.$details = $( "" ); PAGE.id      = 0; $tables.each( PAGE.furnish ); if ( PAGE.id ) { PAGE.$details.addClass( Signature + "-ul" ); $survey = $( " " ); $survey.addClass( Signature + "-cell" ); $survey.append( $text ); NUM.$group = $( "" ); NUM.$group.addClass( Signature + "-ul" ); for ( i = 0; i < NUM.offer.length;  i++ ) { s  = NUM.offer[ i ]; $li = $( "" ); $li.addClass( Signature + "-ul" ) .on( "click", [ s, $li ],  NUM.flip ) .text( PAGE.flat( NUM.patterns[ s ] ) ); if ( i ) { $li.prepend( $( " " ) ); }              NUM.$group.append( $li ); if ( ! i ) { NUM.flip( s, $li ); }           }   // for i            NUM.furnish; $survey.append( NUM.$group ); $survey.append( PAGE.$details ); PAGE.$box.append( $survey ); } else { $text.addClass( Signature + "-cell" ); PAGE.$box.append( $text ); }     } else { $text.addClass( Signature + "-cell" ); PAGE.$box.append( $text ); }  };   // PAGE.first

PAGE.flat = function ( adjust ) { // Replace entities by characters // Precondition: //   adjust  -- string expected // Uses: //   >  NUM.entities //   >< PAGE.reEntitiy //    < PAGE.reEntitiyX // 2017-11-30 PerfektesChaos@de.wikipedia var r = ( adjust || "ERROR" ), fun10, fun16, s, seek, sign, shift; if ( r.indexOf( "&#" ) >=  0 ) { fun10 = function ( all, adapt ) { return String.fromCharCode( parseInt( adapt, 10 ) ); };        fun16 = function ( all, adapt ) { return String.fromCharCode( parseInt( adapt, 16 ) ); };        if ( typeof PAGE.reEntitiy  !==  "object" ) { PAGE.reEntitiy = new RegExp( "&#([0-9]+);", "g" ); PAGE.reEntitiyX = new RegExp( "&#x([0-9A-F]+);", "gi" ); }        r = r.replace( PAGE.reEntitiy, fun10 ); if ( r.indexOf( "&#x" ) >=  0 ) { r = r.replace( PAGE.reEntitiyX, fun16 ); }     }      if ( r.indexOf( "&" )  >=  0 ) { for ( s in NUM.entities ) { seek = "&" + s + ";"; if ( r.indexOf( seek ) >=  0 ) { shift = NUM.entities[ s ]; sign = "re_" + s;               if ( typeof PAGE[ sign ]  !==  "object" ) { PAGE[ sign ] = new RegExp( seek, "g" ); }              if ( shift ) { shift = String.fromCharCode( shift ); } else { shift = ""; }              r = r.replace( PAGE[ sign ], shift ); break;  // for s in NUM.entities }        }   // for s in NUM.entities }     return r;   };   // PAGE.flat

PAGE.fruit = function ( assign ) { // Make selected data available for copy&paste // Precondition: //   assign  -- string, to be copied to clipboard textarea // Uses: //   >  Signature //   >  PAGE.$box //   >< PAGE.$textarea // 2020-07-25 PerfektesChaos@de.wikipedia if ( ! PAGE.$textarea ) { PAGE.$textarea = $( " " ); PAGE.$textarea.addClass( Signature + "-textarea" ) .attr( { id:       Signature + "-copy",                                readonly: "readonly",                                rows:     "5" } ); PAGE.$box.after( PAGE.$textarea ); }     PAGE.$textarea.val( assign ); };  // PAGE.fruit

PAGE.furnish = function ( i, e ) { // Initialize data table // Precondition: //   i  -- index number //   e  -- DOM element // Uses: //   >  Signature //   >  PAGE.sign //   >  PAGE.details //   >< PAGE.id      //    TABLE.fiat //   (TABLE.furnish) // 2020-08-21 PerfektesChaos@de.wikipedia var $table  = $( e ).eq( 0 ), s, $a, $caption, $handle, $li; if ( $table.find( "thead" ).length ||           $table.find( "th" ).length ) { $a = $( "" ); $li = $( "" ); if ( PAGE.id ) { $li.append( $( " " ) ); }        ++PAGE.id; s = Signature + "-" + PAGE.id; $a.attr( { href: "#" + s } ) .text( PAGE.id ); $li.append( $a ); PAGE.$details.append( $li ); TABLE.fiat( $table, PAGE.id ); $caption = $table.find( "caption" ).eq( 0 ); $handle = $( " " ); if ( ! $caption.length ) { $caption = $( " " ); $table.prepend( $caption ); }        $handle.addClass( Signature + "-handle" ) .attr( { id:   s,                         title: Signature } ) .text( PAGE.sign ) .on( "click", $table, TABLE.furnish ); $caption.addClass( Signature + "-caption" ); $caption.append( $handle ); }     return true; };  // PAGE.furnish

REPO.feed = function ( sign, val ) { // Store value at sign // Precondition: //   sign   -- string, with group ID      //    val    -- any value // Uses: //   >< REPO.o      //    REPO.fetch // 2020-08-21 PerfektesChaos@de.wikipedia var webSs; if ( typeof REPO.o !==  "object" ) { REPO.fetch( "" ); }     REPO.o[ sign ] = val; if ( typeof window.localStorage ===  "object" ) { webSs = window.localStorage; if ( webSs  &&   typeof webSs.setItem  ===  "function" ) { try { webSs.setItem( REPO.full,                             JSON.stringify( REPO.o ) ); } catch (e) { }        }      }   };   // REPO.feed

REPO.fetch = function ( sign ) { // Retrieve value at sign // Precondition: //   sign   -- string, with group ID      // Uses: //    < REPO.o      //    REPO.full // 2020-08-21 PerfektesChaos@de.wikipedia var got, r, webSs; if ( typeof REPO.o !==  "object"   &&           typeof window.localStorage  ===  "object" ) { webSs = window.localStorage; if ( webSs  &&   typeof webSs.getItem  ===  "function" ) { try { got = JSON.parse( webSs.getItem( REPO.full ) ); if ( typeof got ===  "object"                    &&     got ) { REPO.o = got; }           } catch (e) { }        }      }      if ( typeof REPO.o  !==  "object" ) { REPO.o = { }; }     if ( typeof REPO.o[ sign ]  !==  "undefined" ) { r = REPO.o[ sign ]; }     return r;   };   // REPO.fetch

REPO.first = function { // Initialize memory // Uses: //   >  Signature //   >  JSON //    < BACKUP.repo //   mw.storage.get // 2020-01-05 PerfektesChaos@de.wikipedia var stored; if ( typeof REPO.repo ===  "undefined"   &&           typeof mw  ===  "object"           &&     mw   &&           typeof mw.storage  ===  "object"           &&     mw.storage   &&           typeof mw.storage.get  ===  "function" ) { REPO.repo = false; stored   = mw.storage.get( Signature ); if ( stored ) { try { REPO.repo = JSON.parse( stored ); if ( typeof REPO.repo !==  "object"                    ||   ! REPO.repo ) { REPO.repo = false; }           } catch( ex ) { }        }      }   };   // REPO.first

REPO.full = function { // Provide project selector // Uses: //   >  Signature //   >< REPO.sign //   mw.config.get // 2017-10-01 PerfektesChaos@de.wikipedia if ( typeof REPO.sign !==  "string" ) { REPO.sign = Signature + "." + mw.config.get( "wgDBname" ); }     return REPO.sign; };  // REPO.full

TABLE.facilitate = function ( $all, $at ) { // Cell equipping, if not yet done // Precondition: //   $all  -- //   $at   -- / // Uses: //   >  Signature //   (TABLE.flipper) // 2017-11-30 PerfektesChaos@de.wikipedia var s = "." + Signature, $w = $at.find( s + "-exclude" ); if ( $w.length ) { $w.show; $at.find( s + "-include" ).hide; } else { $w = $( " " ); $w.addClass( Signature + "-exclude " + Signature + "-toggle" ) .on( "click",               [ $all, $at, false ],                TABLE.flipper ) .text( "[-]" ); $at.append( $w ); $w = $( " " ); $w.addClass( Signature + "-include " + Signature + "-toggle" ) .hide .on( "click",               [ $all, $at, true ],                TABLE.flipper ) .text( "[+]" ); $at.append( $w ); }  };   // TABLE.facilitate

TABLE.factory = function ( $all ) { // Retrieve completed regular mirror table // Precondition: //   $all  -- //   assigned mirror table has been prepared //                                  .nC      //                                   .nR      //                                   .$rows //                                  .d      // Postcondition: //   Returns complete assigned mirror table // Uses: //   >< TABLE.reInteger //   TABLE.fiat // 2020-08-25 PerfektesChaos@de.wikipedia var r = TABLE.fiat( $all ), e, i, j, k, m, n, s, tmp, ts, $row, $rows, $t; if ( ! r.d ) { if ( typeof TABLE.reInteger !==  "object" ) { TABLE.reInteger = new RegExp( "^[0-9]+$" ); }        $rows = r[ "$rows" ]; for ( i = 0; i < r.nR;  i++ ) { n = $rows.eq( i ).children.length -  1; if ( n > r.nC ) { r.nC = n;           } }  // for i         r.d = [ ]; tmp = [ ]; for ( i = 0; i < r.nR;  i++ ) { ts = [ ]; r.d.push( new Array( r.nC ) ); $row = $rows.eq( i ).children; for ( k = 1; k < $row.length;  k++ ) { ts.push( $row.eq( k ) ); }  // for k            tmp.push( ts ); }  // for i         delete r[ "$rows" ]; do {  // while  $t i = 0; $t = false; do {  // while  i < r.nR               ts = tmp[ i ]; if ( ts ) { $t = ts[ 0 ]; if ( ts.length <= 1 ) { tmp[ i ] = false; } else { tmp[ i ].splice( 0, 1 ); }                 s  = $t.attr( "colspan" ); if ( s  &&   TABLE.reInteger.test( s ) ) { j = ( parseInt( s, 10 ) ||  1 ); } else { j = 1; }                 s  = $t.attr( "rowspan" ); if ( s  &&   TABLE.reInteger.test( s ) ) { n = ( parseInt( s, 10 ) ||  1 ); } else { n = 1; }                 n = Math.min( i + n,  r.nR ); for ( i < n; i++ ) { e = r.d[ i ]; m = 0; do {  // while  m < r.nC                        if ( ! e[ m ] ) { k = Math.min( m + j, r.nC ); for ( m < k; m++ ) { r.d[ i ][ m ] = $t; }  // for m                           break;   // while  m < r.nC                        } m++; } while ( m < r.nC ); }  // for i               } else { i++; }           } while ( i < r.nR ); } while ( $t ); TABLE.fiat( $all, false, r ); }     return r.d;   };   // TABLE.factory

TABLE.fiat = function ( $all, assign, apply ) { // Create or assign regular mirror table // Precondition: //   $all    -- //   assign  -- number, with ID, to be assigned to $all //   apply   -- regular mirror table to be stored // Postcondition: //   Returns any assigned mirror table, if not assigning // Uses: //   >  Signature // 2020-08-21 PerfektesChaos@de.wikipedia var r;     if ( typeof assign  ===  "number" ) { $all.data( Signature, "" + assign ); } else { r = $all.data( Signature ); if ( apply ) { TABLE.t[ r ] = apply; r           = apply; } else { if ( typeof TABLE.t !==  "object" ) { TABLE.t = { }; }           if ( typeof TABLE.t[ r ]  !==  "object" ) { TABLE.t[ r ] = { d: false }; }           r = TABLE.t[ r ]; }     }      return r;   };   // TABLE.fiat

TABLE.flat = function ( $assembly ) { // Normalize single row against colspan etc.     // Precondition: //   $assembly  -- // Postcondition: //   $assembly is split into single cells. //   Returns number of columns or rows // Uses: //   >  Signature //   >< TABLE.reInteger // 2017-11-30 PerfektesChaos@de.wikipedia var $row = $assembly.children, r   = $row.length, fine = function { if ( typeof TABLE.reInteger !==  "object" ) { TABLE.reInteger = new RegExp( "^[0-9]+$" ); }                },          i, m, s, $t; for ( i = r - 1; i >= 0;  i-- ) { $t = $row.eq( i ); s = $t.attr( "rowspan" ); if ( s ) { fine; if ( TABLE.reInteger.test( s ) ) { m = parseInt( s, 10 ); } else { m = 0; }           if ( m < 2 ) { $t.attr( { rowspan: null } ); }        }         s  = $t.attr( "colspan" ); if ( s ) { fine; if ( TABLE.reInteger.test( s ) ) { m = parseInt( s, 10 ); if ( m > 1 ) { r = r + m - 1; }           } else { m = 0; }           if ( m < 2 ) { $t.attr( { colspan: null } ); }        }      }   // for i-- return r;  };   // TABLE.flat

TABLE.flatten = function ( $all ) { // Remove sortability etc.     // Precondition: //   $all  -- // Postcondition: //   Sortability removed // 2020-08-28 PerfektesChaos@de.wikipedia var $clickable; if ( $all.hasClass( "sortable" ) ) { $all.removeClass( "sortable jquery-tablesorter" ); $clickable = $all.children( "thead" ).find( "th" ); $clickable.off( "click" ) .off( "keypress" ) .off( "mousedown" ); }     $all.removeClass( "mw-datatable" ); };  // TABLE.flatten

TABLE.flip = function ( action ) { // Widget usage // Precondition: //   action  -- event data //              .data //              [0]  --       //               [1]  -- true: horizontal, false: column //              [2]  -- number of row or column //              [3]  -- activity code // Postcondition: //   Performed. // Uses: //   >  Signature //   >  NUM.call //   NUM.fore //   TABLE.focus //   NUM.first // 2020-08-27 PerfektesChaos@de.wikipedia var k, line, query, s, s1, s2, $active, $table, $tbody, $td, $thead, $tr; if ( typeof action ===  "object"           &&     action   &&           typeof action.data ===  "object"           &&     action.data ) { s = "." + Signature; $table = action.data[ 0 ]; line  = action.data[ 1 ]; k     = action.data[ 2 ]; query = action.data[ 3 ]; $tbody = $table.find( "tbody" ); if ( line ) { $tr   = $tbody.children( "tr" ).eq( k ); $tr   = $tr.children; $td   = $tr.eq( 0 ); } else { $thead = $table.find( "thead" ); $tr   = $thead.children( "tr" ).eq( 0 ); $td   = $tr.children( "td" ).eq( k ); }        $table.find( s + "-result" ).remove; NUM.fore( $tbody ); s1 = Signature + "-chosen"; $table.find( "." + s1 ).removeClass( s1 ); if ( typeof query ===  "boolean" ) { s1     = Signature + "-active"; $active = $tbody.find( "." + s1 ); $active.removeClass( s1 ); $tbody.find( s + "-exclude" ).hide; $tbody.find( s + "-include" ).hide; s1 = s + "-menu"; s2 = s + "-widget"; $table.find( s1 ).hide; $table.find( s2 ).css( { visibility: "visible" } ); $active = $table.find( s + "-quit" ).children; if ( query ) { $td.find( s2 ).css( { visibility: "hidden" } ); $td.find( s1 ).show; TABLE.focus( $table, $tbody, line, k ); $active.show; } else { $active.hide; }        } else { $td.find( "." + Signature + "-" + NUM.call[ query ] ) .addClass( s1 ); $active = $( " " ); $active.addClass( Signature + "-result" ) .data( "query", query ) .append( $( " " ) ); $td.append( $active ); NUM.first( $table, query, $active ); }     }   };   // TABLE.flip

TABLE.flipper = function ( action, abort ) { // Cell toggle // Precondition: //   action  -- event data //              .data //              [0]  --       //               [1]  -- /       //               [2]  -- true: +, false: - //   abort   -- true: no propagation to result // Postcondition: //   Toggled. // Uses: //   >  Signature //   NUM.fore //   NUM.fire // 2020-08-21 PerfektesChaos@de.wikipedia var less, s, sub, $ex, $in, $t, $table; if ( typeof action ===  "object"           &&     action   &&           typeof action.data  ===  "object"           &&     action.data ) { $table = action.data[ 0 ]; $t    = action.data[ 1 ]; less  = action.data[ 2 ]; s     = "." + Signature; sub   = Signature + "-active"; $ex   = $t.find( s + "-exclude" ); $in   = $t.find( s + "-include" ); if ( less ) { $t.addClass( sub ); $in.hide; $ex.show; } else { $t.removeClass( sub ); $ex.hide; $in.show; NUM.fore( $t ); }        if ( ! abort ) { NUM.fire( $table ); }     }   };   // TABLE.flipper

TABLE.focus = function ( $all, $area, align, at ) { // Prepare single table for expansion // Precondition: //   $all    -- //   $area   -- //   align   -- true: horizontal, false: column //   at      -- number of row or column // Postcondition: // Uses: //   >  Signature //   TABLE.factory //   TABLE.facilitate // 2020-08-27 PerfektesChaos@de.wikipedia var s    = Signature + "-active", table = TABLE.factory( $all ), i, k, row, $cells, $t; if ( align ) { row = table[ at ]; for ( i = 0; i < row.length;  i++ ) { $t = row[ i ]; if ( $t ) { $t.addClass( s ); }        }   // for k      } else { k = at - 1; for ( i = 0; i < table.length;  i++ ) { $t = table[ i ][ k ]; if ( $t ) { $t.addClass( s ); }        }   // for i      } $cells = $area.find( "." + s ); for ( k = 0; k < $cells.length;  k++ ) { TABLE.facilitate( $all, $cells.eq( k ) ); }  // for k   };   // TABLE.focus

TABLE.$fold = function ( $all, align, at ) { // Create control header cell // Precondition: //   $all   -- //   align  -- true: horizontal, false: column //   at     -- number of row or column // Postcondition: //   Returns // Uses: //   >  Signature //   >  NUM.starts //   >  NUM.call //   >  PAGE.sign //   (TABLE.flip) // 2020-08-27 PerfektesChaos@de.wikipedia var $r      = $( " " ), $widget = $( " " ), $menu   = $( " " ), $space  = $( " " ).text( " " ), i, s, $e; $menu.addClass( Signature + "-menu" ) .hide; for ( i = 0; i < NUM.starts.length;  i++ ) { s = NUM.starts.substr( i, 1 ); $e = $( " " ); $e.addClass( Signature + "-" + NUM.call[ s ] ) .on( "click",                [ $all, align, at, s ],                 TABLE.flip ); if ( s === "?" ) { s = ( align ? "h" : "v" ); }        $e.text( TABLE.title[ s ] ); $menu.append( $e ) .append( $space.clone ); }  // for i      if ( align ) { $r.data( "row", "" + at ); }     $widget.addClass( Signature + "-widget" ) .on( "click",                 [ $all, align, at, true ],                  TABLE.flip ) .text( PAGE.sign ); $r.append( $widget ) .append( $menu ) .addClass( Signature + "-td" ); return $r; };  // TABLE.$fold

TABLE.furnish = function ( action ) { // Prepare single table for expansion // Precondition: //   action  -- event data //              .target // Uses: //   >  Signature //   >  PAGE.$details //   TABLE.flatten //   TABLE.fiat //   TABLE.$fold // 2023-04-19 PerfektesChaos@de.wikipedia var e, i, k, n, sign, table, $caption, $handle, $rows, $table, $tbody, $td, $tfoot, $thead, $tr, $x; if ( typeof action ===  "object"           &&     action   &&           typeof action.target  ===  "object"           &&     action.target ) { $handle = $( action.target ); sign    = $handle.attr( "id" ); $caption = $handle.parent; $table  = $caption.parent; $handle.remove; }     if ( $table ) { TABLE.flatten( $table ); $thead = $table.find( "thead" ); if ( ! $thead.length ) { $thead = $( " " ); $rows = $table.find( "tr" ); for ( i = 0; i < $rows.length;  i++ ) { $tr = $rows.eq( i ); $x = $tr.children; for ( k = 0; k < $x.length;  k++ ) { e = $x.eq( k ).get( 0 ); if ( e.tagName.toUpperCase !== "TH" ) { $tr = false; break;  // for k                  } }  // for k               if ( $tr ) { $tr.detach; $thead.append( $tr ); } else { break;  // for i               } }  // for i            $caption.after( $thead ); }        $tfoot = $table.find( "tfoot" ); if ( $tfoot.length ) { $rows = $tfoot.find( "tr" ); $td  = $( " " ); $td.addClass( Signature + "-active" ); if ( $rows.length > 1 ) { $td.attr( { rowspan: $rows.length } ); }           $rows.eq( 0 ).prepend( $td ); }        $tbody = $table.find( "tbody" ); if ( ! $tbody.length ) { $tbody = $( " " ); $rows = $table.children( "tr" ); for ( i = 0; i < $rows.length;  i++ ) { $tr = $rows.eq( i ); $tr.detach; $tbody.append( $tr ); }  // for i            $thead.after( $tbody ); }        $rows = $tbody.children; n    = $rows.length; if ( n ) { table           = TABLE.fiat( $table ); table[ "$rows" ] = $rows; table.nR        = n;            $rows            = $thead.children; k               = TABLE.flat( $rows.eq( 0 ) ); table.nC        = k;            k++; $td = $( " " ); $x = $( " " ); $x.hide .on( "click",                  [ $table, true, 0, false ],                   TABLE.flip ) .text( TABLE.title.X ); $td.addClass( Signature + "-active " + Signature + "-quit" ) .attr( { id:      sign,                        rowspan:  $rows.length + 1 } ) .append( $x ); $tr = $( " " ); $tr.append( $td ); for ( i = 1; i < k;  i++ ) { $tr.append( TABLE.$fold( $table, false, i ) ); }  // for i            $thead.prepend( $tr ); for ( i = 0; i < n;  i++ ) { $tr = table[ "$rows" ].eq( i ); $tr.prepend( TABLE.$fold( $table, true, i ) ); }  // for i         } else { PAGE.$details.find( "a[href$=\"#" + sign + "\"]" ) .parent .remove; }     }   };   // TABLE.furnish

fire; }( window.mediaWiki, window.jQuery ) );

// Emacs // Local Variables: // coding: utf-8-unix // fill-column: 80 // End:

/// EOF  tableXpander.js